home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianFilters.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  70KB  |  2,879 lines

  1. /*ScianFilters.c
  2.   Eric Pepke
  3.   Oct 3, 1991
  4.   Stuff for Filters
  5. */
  6.  
  7. #include "Scian.h"
  8. #include "ScianTypes.h"
  9. #include "ScianLists.h"
  10. #include "ScianIcons.h"
  11. #include "ScianWindows.h"
  12. #include "ScianObjWindows.h"
  13. #include "ScianVisWindows.h"
  14. #include "ScianButtons.h"
  15. #include "ScianSliders.h"
  16. #include "ScianTextBoxes.h"
  17. #include "ScianTitleBoxes.h"
  18. #include "ScianControls.h"
  19. #include "ScianDatasets.h"
  20. #include "ScianErrors.h"
  21. #include "ScianColors.h"
  22. #include "ScianDialogs.h"
  23. #include "ScianStyle.h"
  24. #include "ScianSpaces.h"
  25. #include "ScianIDs.h"
  26. #include "ScianArrays.h"
  27. #include "ScianMethods.h"
  28. #include "ScianDepend.h"
  29. #include "ScianFilters.h"
  30. #include "ScianObjFunctions.h"
  31. #include "ScianScales.h"
  32. #include "ScianTemplates.h"
  33. #include "ScianTemplateHelper.h"
  34.  
  35. ObjPtr filterClass;
  36. ObjPtr orthoSlicerClass, vectorJoinerClass, fixedSlicerClass, missingDataClass;
  37. ObjPtr registeredEasyFilters, registeredMainFilters;
  38. static Bool justAdding = false;        /*True iff we're just adding controls*/ 
  39.  
  40. /****************************************************************************/
  41. /*                             Vector Joiner                                */
  42. /****************************************************************************/
  43.  
  44. static ObjPtr InitVectorJoiner(joiner, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  45. ObjPtr joiner, dataset;
  46. long desFlags;
  47. int desTopDim, desSpatDim, desNComponents;
  48. /*Initializes a vector joiner
  49.     joiner        the joiner
  50.     dataset        the dataset to slice
  51.     desFlags    the desired flags of the result
  52.     desTopDim    the desired topological dimension
  53.     desSpatDim    the desired spatial dimension
  54.     desNComponents    the desired number of components
  55.  
  56. Returns ObjTrue if successful, ObjFalse if not
  57. */
  58. {
  59.     long sourceInfo;
  60.     ObjPtr var;
  61.     int sourceTop, sourceSpatial, sourceNComponents;
  62.     ObjPtr icon;
  63.     ObjPtr dimValues;
  64.     real *elements;
  65.     int k;
  66.     ObjPtr dataForm;
  67.     ThingListPtr runner;
  68.  
  69.     /*Can only deal with a list of datasets*/
  70.     if (!IsList(dataset))
  71.     {
  72.     return ObjFalse;
  73.     }
  74.  
  75. #if 0
  76.     /*Look through the datasets, checking forms*/
  77.  
  78.     sourceInfo = GetDatasetInfo(dataset);
  79.     sourceTop = GetTopDim(dataset);
  80.     sourceSpatial = GetSpatialDim(dataset);
  81.  
  82.     /*Check the info*/
  83.     if (sourceInfo & DS_UNSTRUCTURED ||
  84.     !(sourceInfo & DS_HASFIELD))
  85.     {
  86.     return ObjFalse;
  87.     }
  88.  
  89.     if (desFlags & DS_UNSTRUCTURED ||
  90.     !(desFlags & DS_HASFIELD))
  91.     {
  92.     return ObjFalse;
  93.     }
  94.  
  95.     if (sourceInfo & (DS_VECTOR) != desFlags & (DS_VECTOR))
  96.     {
  97.     return ObjFalse;
  98.     }
  99.  
  100.     /*Check the topological dimension*/
  101.     if (desTopDim >= 0 && desTopDim >= sourceTop)
  102.     {
  103.     return ObjFalse;
  104.     }
  105.     if (desTopDim < 0) desTopDim = sourceTop - 1;
  106.  
  107.     /*Check the spatial dimension*/
  108.     if (desSpatDim >= 0 && desSpatDim != sourceSpatial)
  109.     {
  110.     return ObjFalse;
  111.     }
  112.     if (desSpatDim < 0) desSpatDim = sourceSpatial;
  113.  
  114.     /*Check the n components*/
  115.     var = GetVar(dataset, NCOMPONENTS);
  116.     if (var)
  117.     {
  118.     sourceNComponents = GetInt(var);
  119.     }
  120.     else
  121.     {
  122.     sourceNComponents = 1;
  123.     }
  124.     if (desNComponents >= 0 && sourceNComponents != desNComponents)
  125.     {
  126.     return ObjFalse;
  127.     }
  128.     if (desNComponents < 0) desNComponents = sourceNComponents;
  129.  
  130.     /*OK now*/
  131.  
  132.     /*Choose an icon*/
  133.     switch(desTopDim)
  134.     {
  135.     case 0:
  136.     case 1:
  137.         icon = sourceInfo & DS_VECTOR ? icon1DVector : icon1DScalar;
  138.         break;
  139.     case 2:
  140.         icon = sourceInfo & DS_VECTOR ? icon2DVector : icon2DScalar;
  141.         break;
  142.     case 3:
  143.         icon = sourceInfo & DS_VECTOR ? icon3DVector : icon3DScalar;
  144.         break;
  145.     default:
  146.         icon = sourceInfo & DS_VECTOR ? icon4DVector : icon4DScalar;
  147.         break;
  148.     }
  149.  
  150.     icon = NewObject(icon, 0);
  151.     SetVar(slicer, DEFAULTICON, icon);
  152.  
  153.     SetVar(slicer, NAME, GetVar(dataset, NAME));
  154.     SetVar(icon, NAME, GetVar(dataset, NAME));
  155.  
  156.     /*Set the dataset*/
  157.     SetVar(slicer, MAINDATASET, dataset);
  158.  
  159.     /*Create the DIMVALUES*/
  160.     dimValues = NewRealArray(1, (long) sourceTop);
  161.     elements = ELEMENTS(dimValues);
  162.     for (k = 0; k < sourceTop; ++k)
  163.     {
  164.     elements[k] = (k >= desTopDim) ? 0.0: -1.0;
  165.     }
  166.     SetVar(slicer, DIMVALUES, dimValues);
  167. #endif
  168.     return ObjTrue;
  169. }
  170.  
  171. static ObjPtr AllVectorJoiners(joinerClass, datasets)
  172. ObjPtr joinerClass, datasets;
  173. /*Returns a list of all possible vector joiners that can be made with dataset, or null*/
  174. {
  175.     long sourceInfo;
  176.     long desFlags;
  177.     ObjPtr var;
  178.     int sourceTop, sourceSpatial, sourceNComponents;
  179.     int desTop, desSpatial, desNComponents;
  180.     ObjPtr icon;
  181.     ObjPtr dimValues;
  182.     real *elements;
  183.     int k;
  184.     ObjPtr retVal;
  185.     ObjPtr dataset;
  186.     ThingListPtr listPtr;
  187.  
  188.     /*Cannot deal with anything other than a list of datasets*/
  189.     if (!IsList(datasets))
  190.     {
  191.     return NULLOBJ;
  192.     }
  193.  
  194.     listPtr = LISTOF(datasets);
  195.     if (!listPtr)
  196.     {
  197.     return NULLOBJ;
  198.     }
  199.  
  200.     dataset = listPtr -> thing;
  201.  
  202.     sourceInfo = GetDatasetInfo(dataset);
  203.     sourceTop = GetTopDim(dataset);
  204.     sourceSpatial = GetSpatialDim(dataset);
  205.  
  206.     desFlags = sourceInfo;
  207.  
  208.     desSpatial = sourceSpatial;
  209.     /*Check the n components*/
  210.     var = GetVar(dataset, NCOMPONENTS);
  211.     if (var)
  212.     {
  213.     sourceNComponents = GetInt(var);
  214.     }
  215.     else
  216.     {
  217.     sourceNComponents = 1;
  218.     }
  219.     desNComponents = sourceNComponents;
  220.  
  221.     desTop = sourceTop;
  222.     retVal = NULLOBJ;
  223.     {
  224.     ObjPtr joiner;
  225.  
  226.     joiner = NewObject(joinerClass, 0);
  227.     if (IsTrue(InitFilter(joiner, datasets, desFlags, desTop, desSpatial, desNComponents)))
  228.     {
  229.         if (!retVal)
  230.         {
  231.         retVal = NewList();
  232.         }
  233.         PrefixList(retVal, joiner);
  234.     }
  235.     }
  236.  
  237.     return retVal;
  238. }
  239.  
  240. /****************************************************************************/
  241. /*                              Ortho Slicer                                */
  242. /****************************************************************************/
  243.  
  244. static ObjPtr InitOrthoSlicer(slicer, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  245. ObjPtr slicer, dataset;
  246. long desFlags;
  247. int desTopDim, desSpatDim, desNComponents;
  248. /*Initializes ann ortho slicer
  249.     slicer        the slicer
  250.     dataset        the dataset to slice
  251.     desFlags    the desired flags of the result
  252.     desTopDim    the desired topological dimension
  253.     desSpatDim    the desired spatial dimension
  254.     desNComponents    the desired number of components
  255.  
  256. Returns ObjTrue if successful, ObjFalse if not
  257. */
  258. {
  259.     long sourceInfo;
  260.     ObjPtr var;
  261.     int sourceTop, sourceSpatial, sourceNComponents;
  262.     ObjPtr icon;
  263.     ObjPtr dimValues;
  264.     ObjPtr formDims;
  265.     ObjPtr dimChanges;
  266.     real *elements;
  267.     int k;
  268.  
  269.     /*Cannot deal with a list of datasets*/
  270.     if (IsList(dataset))
  271.     {
  272.     return ObjFalse;
  273.     }
  274.  
  275.     sourceInfo = GetDatasetInfo(dataset);
  276.     sourceTop = GetTopDim(dataset);
  277.     sourceSpatial = GetSpatialDim(dataset);
  278.  
  279.     /*Check the info*/
  280.     if (sourceInfo & DS_UNSTRUCTURED ||
  281.     !(sourceInfo & DS_HASFIELD))
  282.     {
  283.     return ObjFalse;
  284.     }
  285.  
  286.     if (desFlags & DS_UNSTRUCTURED ||
  287.     !(desFlags & DS_HASFIELD))
  288.     {
  289.     return ObjFalse;
  290.     }
  291.     if ((sourceInfo & (DS_VECTOR)) != (desFlags & (DS_VECTOR)))
  292.     {
  293.     return ObjFalse;
  294.     }
  295.  
  296.     /*Check the topological dimension*/
  297.     if (desTopDim >= 0 && desTopDim >= sourceTop)
  298.     {
  299.     return ObjFalse;
  300.     }
  301.     if (desTopDim < 0) desTopDim = sourceTop - 1;
  302.  
  303.     /*Check the spatial dimension*/
  304.     if (desSpatDim >= 0 && desSpatDim != sourceSpatial)
  305.     {
  306.     return ObjFalse;
  307.     }
  308.     if (desSpatDim < 0) desSpatDim = sourceSpatial;
  309.  
  310.     /*See if any of the dimensions is degenerate*/
  311.     formDims = GetDatasetFormDims(dataset);
  312.     if (!formDims)
  313.     {
  314.     return ObjFalse;
  315.     }
  316.     elements = ELEMENTS(formDims);
  317.  
  318.     for (k = 0; k < DIMS(formDims)[0]; ++k)
  319.     {
  320.     if (elements[k] < 1.5)
  321.     {
  322.         return ObjFalse;
  323.     }
  324.     }
  325.  
  326.     /*Check the n components*/
  327.     var = GetVar(dataset, NCOMPONENTS);
  328.     if (var)
  329.     {
  330.     sourceNComponents = GetInt(var);
  331.     SetVar(slicer, NCOMPONENTS, var);
  332.     }
  333.     else
  334.     {
  335.     sourceNComponents = 1;
  336.     }
  337.     if (desNComponents >= 0 && (sourceNComponents != desNComponents))
  338.     {
  339.     return ObjFalse;
  340.     }
  341.     if (desNComponents < 0) desNComponents = sourceNComponents;
  342.  
  343.     /*OK now*/
  344.  
  345.     /*Choose an icon*/
  346.     switch(desTopDim)
  347.     {
  348.     case 0:
  349.     case 1:
  350.         icon = sourceInfo & DS_VECTOR ? icon1DVector : icon1DScalar;
  351.         break;
  352.     case 2:
  353.         icon = sourceInfo & DS_VECTOR ? icon2DVector : icon2DScalar;
  354.         break;
  355.     case 3:
  356.         icon = sourceInfo & DS_VECTOR ? icon3DVector : icon3DScalar;
  357.         break;
  358.     default:
  359.         icon = sourceInfo & DS_VECTOR ? icon4DVector : icon4DScalar;
  360.         break;
  361.     }
  362.  
  363.     icon = NewObject(icon, 0);
  364.     SetVar(slicer, DEFAULTICON, icon);
  365.  
  366.     SetVar(slicer, NAME, GetVar(dataset, NAME));
  367.     SetVar(icon, NAME, GetVar(dataset, NAME));
  368.  
  369.     /*Set the dataset*/
  370.     SetVar(slicer, MAINDATASET, dataset);
  371.  
  372.     /*Create the DIMVALUES*/
  373.     dimValues = NewRealArray(1, (long) sourceTop);
  374.     elements = ELEMENTS(dimValues);
  375.     for (k = 0; k < sourceTop; ++k)
  376.     {
  377.     elements[k] = (k >= desTopDim) ? 0.0: -1.0;
  378.     }
  379.     SetVar(slicer, DIMVALUES, dimValues);
  380.  
  381.     /*Create the DIMCHANGES*/
  382.     dimChanges = NewRealArray(1, (long) sourceTop);
  383.     elements = ELEMENTS(dimChanges);
  384.     for (k = 0; k < sourceTop; ++k)
  385.     {
  386.     elements[k] = (real) k;
  387.     }
  388.     SetVar(slicer, DIMCHANGES, dimChanges);
  389.     SetVar(slicer, LASTDIMCHANGED, NewInt(k));
  390.  
  391.     return ObjTrue;
  392. }
  393.  
  394. static ObjPtr AllOrthoSlicers(slicerClass, datasets)
  395. ObjPtr slicerClass, datasets;
  396. /*Returns a list of all possible slicers that can be made with datasets, or null*/
  397. {
  398.     long sourceInfo;
  399.     long desFlags;
  400.     ObjPtr var;
  401.     int sourceTop, sourceSpatial, sourceNComponents;
  402.     int desTop, desSpatial, desNComponents;
  403.     ObjPtr icon;
  404.     ObjPtr dimValues;
  405.     real *elements;
  406.     int k;
  407.     ObjPtr retVal;
  408.     ThingListPtr runner;
  409.  
  410.     retVal = NULLOBJ;
  411.     for (runner = LISTOF(datasets); runner; runner = runner -> next)
  412.     {
  413.     ObjPtr dataset;
  414.     dataset = runner -> thing;
  415.     sourceInfo = GetDatasetInfo(dataset);
  416.     sourceTop = GetTopDim(dataset);
  417.     sourceSpatial = GetSpatialDim(dataset);
  418.  
  419.     /*Check the info*/
  420.     if (sourceInfo & DS_UNSTRUCTURED ||
  421.         !(sourceInfo & DS_HASFIELD))
  422.     {
  423.         continue;
  424.     }
  425.  
  426.     desFlags = sourceInfo;
  427.  
  428.     /*Check the topological dimension*/
  429.     if (sourceTop <= 0)
  430.     {
  431.         continue;
  432.     }
  433.  
  434.     desSpatial = sourceSpatial;
  435.     /*Check the n components*/
  436.     var = GetVar(dataset, NCOMPONENTS);
  437.     if (var)
  438.     {
  439.         sourceNComponents = GetInt(var);
  440.     }
  441.     else
  442.     {
  443.         sourceNComponents = 1;
  444.     }
  445.     desNComponents = sourceNComponents;
  446.  
  447.     retVal = NULLOBJ;
  448.     for (desTop = 0; desTop < sourceTop; ++desTop)
  449.     {
  450.         ObjPtr slicer;
  451.         slicer = NewObject(orthoSlicerClass, 0);
  452.         if (IsTrue(InitFilter(slicer, dataset, desFlags, desTop, desSpatial, desNComponents)))
  453.         {
  454.         if (!retVal)
  455.         {
  456.             retVal = NewList();
  457.         }
  458.         PrefixList(retVal, slicer);
  459.         }
  460.     }
  461.     }
  462.     return retVal;
  463. }
  464.  
  465. static ObjPtr GetOrthoSlicerLongName(slicer)
  466. ObjPtr slicer;
  467. {
  468.     ObjPtr retVal, mainDataset;
  469.  
  470.     sprintf(tempStr, " %d-D slice", GetTopDim(slicer));
  471.     retVal = NewString(tempStr);
  472.     mainDataset = GetVar(slicer, MAINDATASET);
  473.     if (mainDataset)
  474.     {
  475.     retVal = ConcatStrings(GetLongName(mainDataset), retVal);
  476.     }
  477.     return retVal;
  478. }
  479.  
  480. static ObjPtr GetOrthoSlicerTopDim(slicer)
  481. ObjPtr slicer;
  482. /*Returns the topological dimension of slicer*/
  483. {
  484.     ObjPtr dimValues;
  485.     int nDimensions, k;
  486.     real *elements;
  487.  
  488.     MakeVar(slicer, DIMVALUES);
  489.     dimValues = GetArrayVar("GetOrthoSlicerTopDim", slicer, DIMVALUES);
  490.     if (!dimValues)
  491.     {
  492.     return NULLOBJ;
  493.     }
  494.  
  495.     nDimensions = 0;
  496.     elements = ELEMENTS(dimValues);
  497.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  498.     {
  499.     if (elements[k] < -0.5)
  500.     {
  501.         /*Free dimension*/
  502.         ++nDimensions;
  503.     }
  504.     }
  505.  
  506.     return NewInt(nDimensions);
  507. }
  508.  
  509. static ObjPtr GetOrthoSlicerSpatialDim(slicer)
  510. ObjPtr slicer;
  511. /*Returns the spatial dimension of slicer*/
  512. {
  513.     ObjPtr mainDataset;
  514.     mainDataset = GetObjectVar("GetOrthoSlicerSpatialDim", slicer, MAINDATASET);
  515.     if (mainDataset)
  516.     {
  517.     return NewInt(GetSpatialDim(mainDataset));
  518.     }
  519.     else
  520.     {
  521.     return NULLOBJ;
  522.     }
  523. }
  524.  
  525. static ObjPtr GetOrthoSlicerInfo(slicer)
  526. ObjPtr slicer;
  527. /*Gets info for an ortho slicer*/
  528. {
  529.     ObjPtr mainDataset;
  530.     mainDataset = GetObjectVar("GetOrthoSlicerInfo", slicer, MAINDATASET);
  531.     if (mainDataset)
  532.     {
  533.     return NewInt(GetDatasetInfo(mainDataset));
  534.     }
  535.     else
  536.     {
  537.     return NULLOBJ;
  538.     }
  539. }
  540.  
  541. static ObjPtr MakeOrthoSlicerCPalette(slicer)
  542. ObjPtr slicer;
  543. /*Makes the ortho slicers's CPALETTE*/
  544. {
  545.     ObjPtr mainDataset;
  546.     mainDataset = GetObjectVar("MakeOrthoSlicerCPalette", slicer, MAINDATASET);
  547.     if (mainDataset)
  548.     {
  549.     SetVar(slicer, CPALETTE, GetVar(mainDataset, CPALETTE));
  550.     return ObjTrue;
  551.     }
  552.     else
  553.     {
  554.     return ObjFalse;
  555.     }
  556. }
  557.  
  558. static ObjPtr MakeOrthoSlicerDataForm(slicer)
  559. ObjPtr slicer;
  560. /*Makes an ortho slicer's dataform.*/
  561. {
  562.     ObjPtr mainDataset;
  563.  
  564.     mainDataset = GetObjectVar("MakeOrthoSlicerDataForm", slicer, MAINDATASET);
  565.     if (mainDataset)
  566.     {
  567.     SetVar(slicer, DATAFORM, GetVar(mainDataset, DATAFORM));
  568.     return ObjTrue;
  569.     }
  570.     else
  571.     {
  572.     return ObjFalse;
  573.     }
  574. }
  575.  
  576. static ObjPtr GetOrthoSlicerFormDims(slicer)
  577. ObjPtr slicer;
  578. /*Gets form dims for an ortho slicer*/
  579. {
  580.     ObjPtr mainDataset;
  581.     ObjPtr origDims, resultDims, dimValues;
  582.     int nDimensions, k;
  583.     real *el1, *el2, *el3;
  584.  
  585.     mainDataset = GetObjectVar("MakeOrthoSlicerCPalette", slicer, MAINDATASET);
  586.     if (!mainDataset)
  587.     {
  588.     return NULLOBJ;
  589.     }
  590.  
  591.     origDims = GetDatasetFormDims(mainDataset);
  592.     if (!origDims)
  593.     {
  594.     return NULLOBJ;
  595.     }
  596.  
  597.     MakeVar(slicer, DIMVALUES);
  598.     dimValues = GetArrayVar("GetOrthoSlicerTopDim", slicer, DIMVALUES);
  599.     if (!dimValues)
  600.     {
  601.     return NULLOBJ;
  602.     }
  603.  
  604.     nDimensions = 0;
  605.     el1= ELEMENTS(dimValues);
  606.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  607.     {
  608.     if (el1[k] < -0.5)
  609.     {
  610.         /*Free dimension*/
  611.         ++nDimensions;
  612.     }
  613.     }
  614.  
  615.     if (nDimensions == 0)
  616.     {
  617.     return NULLOBJ;
  618.     }
  619.     resultDims = NewRealArray(1, (long) nDimensions);
  620.     el2 = ELEMENTS(origDims);
  621.     el3 = ELEMENTS(resultDims);
  622.     nDimensions = 0;
  623.     
  624.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  625.     {
  626.     if (el1[k] < -0.5)
  627.     {
  628.         /*Free dimension*/
  629.         el3[nDimensions] = el2[k];
  630.         ++nDimensions;
  631.     }
  632.     }
  633.  
  634.     return resultDims;
  635. }
  636.  
  637. static ObjPtr RegisterOrthoSlicerField(slicer, whichField)
  638. ObjPtr slicer;
  639. int whichField;
  640. /*Registers the field for an ortho slicer*/
  641. {
  642.     ObjPtr mainDataset;
  643.     ObjPtr origDims, resultDims, dimValues;
  644.     int nDimensions, k, d, i, comp;
  645.     real *el1, *el2, *el3;
  646.     long *tempIndices;
  647.     long offset;
  648.  
  649.     mainDataset = GetObjectVar("MakeOrthoSlicerCPalette", slicer, MAINDATASET);
  650.     if (!mainDataset)
  651.     {
  652.     return NULLOBJ;
  653.     }
  654.  
  655.     /*Let the main dataset register itself*/
  656.     if (!SetCurField(whichField, mainDataset))
  657.     {
  658.     return ObjFalse;
  659.     }
  660.  
  661.     /*Now edit it, based on dimValues*/
  662.     MakeVar(slicer, DIMVALUES);
  663.     dimValues = GetArrayVar("GetOrthoSlicerTopDim", slicer, DIMVALUES);
  664.     if (!dimValues)
  665.     {
  666.     return NULLOBJ;
  667.     }
  668.  
  669.     /*Calculate the number of dimensions*/
  670.     nDimensions = 0;
  671.     el1= ELEMENTS(dimValues);
  672.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  673.     {
  674.     if (el1[k] < -0.5)
  675.     {
  676.         /*Free dimension*/
  677.         ++nDimensions;
  678.     }
  679.     }
  680.     curFields[whichField] . topDim = nDimensions;
  681.  
  682.     /*Set up some temporary indices for testing*/
  683.     tempIndices = (long *) Alloc(DIMS(dimValues)[0] * sizeof(long));
  684.     if (!tempIndices)
  685.     {
  686.     return ObjFalse;
  687.     }
  688.     el1= ELEMENTS(dimValues);
  689.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  690.     {
  691.     if (el1[k] < -0.5)
  692.     {
  693.         /*Free dimension.  Make it 0*/
  694.         tempIndices[k] = 0;
  695.     }
  696.     else
  697.     {
  698.         /*Not Free.*/
  699.         tempIndices[k] = (long) (el1[k] + 0.5);
  700.     }
  701.     }
  702.  
  703.     /*Go through the components, editing them*/
  704.     for (comp = 0; comp < curFields[whichField] . nComponents; ++comp)
  705.     {
  706.     /*Get the base offset*/
  707.     offset = GetComponentOffset(whichField, comp, tempIndices);
  708.  
  709.     /*Nudge up the base ptr by that offset*/
  710.     if (curFields[whichField] . components[comp] . dataCompressed)
  711.     {
  712.         curFields[whichField] . components[comp] . data . comp += offset;
  713.     }
  714.     else
  715.     {
  716.         curFields[whichField] . components[comp] . data . unComp += offset;
  717.     }
  718.  
  719.     /*Make invalid any fixed indices*/
  720.     for (k = 0; k < curFields[whichField] . components[comp] . nIndices; ++k)
  721.     {
  722.         if (el1[curFields[whichField] . components[comp] . indices[k]] > -0.5)
  723.         {
  724.         /*Fixed index, already accounted for*/
  725.         curFields[whichField] . components[comp] . indices[k] = -1;
  726.         }
  727.         else
  728.         {
  729.         /*Variable index, have to shift down*/
  730.         d = 0;
  731.         for (i = 0; i < curFields[whichField] . components[comp] . indices[k]; ++i)
  732.         {
  733.             if (el1[i] < -0.5)
  734.             {
  735.             ++d;
  736.             }
  737.         }
  738.         curFields[whichField] . components[comp] . indices[k] = d;
  739.         }
  740.     }
  741.     }
  742.     
  743.     Free(tempIndices);
  744.     return ObjTrue;
  745. }
  746.  
  747. static ObjPtr RegisterOrthoSlicerForm(slicer, whichField)
  748. ObjPtr slicer;
  749. int whichField;
  750. /*Registers the form for an ortho slicer*/
  751. {
  752.     ObjPtr mainDataset;
  753.     ObjPtr origDims, resultDims, dimValues;
  754.     int nDimensions, k, d, i, comp;
  755.     real *el1, *el2, *el3;
  756.     long *tempIndices;
  757.     long offset;
  758.  
  759.     mainDataset = GetObjectVar("MakeOrthoSlicerCPalette", slicer, MAINDATASET);
  760.     if (!mainDataset)
  761.     {
  762.     return NULLOBJ;
  763.     }
  764.  
  765.     /*Let the main dataset register itself*/
  766.     if (!SetCurForm(whichField, mainDataset))
  767.     {
  768.     return ObjFalse;
  769.     }
  770.  
  771.     /*Now edit it, based on dimValues*/
  772.     MakeVar(slicer, DIMVALUES);
  773.     dimValues = GetArrayVar("GetOrthoSlicerTopDim", slicer, DIMVALUES);
  774.     if (!dimValues)
  775.     {
  776.     return NULLOBJ;
  777.     }
  778.  
  779.     /*Calculate the number of dimensions*/
  780.     nDimensions = 0;
  781.     el1= ELEMENTS(dimValues);
  782.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  783.     {
  784.     if (el1[k] < -0.5)
  785.     {
  786.         /*Free dimension*/
  787.         ++nDimensions;
  788.     }
  789.     }
  790.     curFields[whichField] . topDim = nDimensions;
  791.  
  792.     /*Set up some temporary indices for testing*/
  793.     tempIndices = (long *) Alloc(DIMS(dimValues)[0] * sizeof(long));
  794.     if (!tempIndices)
  795.     {
  796.     return ObjFalse;
  797.     }
  798.     el1= ELEMENTS(dimValues);
  799.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  800.     {
  801.     if (el1[k] < -0.5)
  802.     {
  803.         /*Free dimension.  Make it 0*/
  804.         tempIndices[k] = 0;
  805.     }
  806.     else
  807.     {
  808.         /*Not Free.*/
  809.         tempIndices[k] = (long) (el1[k] + 0.5);
  810.     }
  811.     }
  812.  
  813.     /*Go through the components, editing them*/
  814.     for (comp = 0; comp < curFields[whichField] . nComponents; ++comp)
  815.     {
  816.     /*Get the base offset*/
  817.     offset = GetComponentOffset(whichField, comp, tempIndices);
  818.     
  819.     /*Nudge up the base ptr by that offset*/
  820.     if (curFields[whichField] . components[comp] . dataCompressed)
  821.     {
  822.         curFields[whichField] . components[comp] . data . comp += offset;
  823.     }
  824.     else
  825.     {
  826.         curFields[whichField] . components[comp] . data . unComp += offset;
  827.     }
  828.  
  829.     /*Make invalid any fixed indices*/
  830.     for (k = 0; k < curFields[whichField] . components[comp] . nIndices; ++k)
  831.     {
  832.         if (el1[curFields[whichField] . components[comp] . indices[k]] > -0.5)
  833.         {
  834.         /*Fixed index, already accounted for*/
  835.         curFields[whichField] . components[comp] . indices[k] = -1;
  836.         }
  837.         else
  838.         {
  839.         /*Variable index, have to shift down*/
  840.         d = 0;
  841.         for (i = 0; i < curFields[whichField] . components[comp] . indices[k]; ++i)
  842.         {
  843.             if (el1[i] < -0.5)
  844.             {
  845.             ++d;
  846.             }
  847.         }
  848.         curFields[whichField] . components[comp] . indices[k] = d;
  849.         }
  850.     }
  851.     }
  852.     
  853.     Free(tempIndices);
  854.     return ObjTrue;
  855. }
  856.  
  857. static ObjPtr ChangeOrthoSlice(slider)
  858. ObjPtr slider;
  859. /*Changes an ortho slice based on a slider*/
  860. {
  861.     ObjPtr slicer, var;
  862.     real value;
  863.     int whichDimension;
  864.     real *el1; 
  865.  
  866.     slicer = GetObjectVar("ChangeOrthoSlice", slider, REPOBJ);
  867.     if (!slicer)
  868.     {
  869.     return NULLOBJ;
  870.     }
  871.  
  872.     var = GetValue(slider);
  873.     if (!var)
  874.     {
  875.     return NULLOBJ;
  876.     }
  877.     value = GetReal(var);
  878.  
  879.     var = GetIntVar("ChangeOrthoSlice", slider, WHICHINDEX);
  880.     if (!var)
  881.     {
  882.     return ObjFalse;
  883.     }
  884.     whichDimension = GetInt(var);
  885.  
  886.     var = GetArrayVar("ChangeOrthoSlice", slicer, DIMVALUES);
  887.     if (!var)
  888.     {
  889.     return ObjFalse;
  890.     }
  891.     el1 = ELEMENTS(var);
  892.  
  893.     /*Change the dimension to be the value*/
  894.     var = NewRealArray(1, DIMS(var)[0]);
  895.     CArray2Array(var, el1);
  896.     el1 = ELEMENTS(var);
  897.     el1[whichDimension] = value;
  898.     SetVar(slicer, DIMVALUES, var);
  899.  
  900.     ImInvalid(slicer);
  901.     SetVar(slicer, APPEARANCE, ObjTrue);
  902.     return ObjTrue;
  903. }
  904.  
  905. static ObjPtr MakeOrthoSliceAppearance(slider)
  906. ObjPtr slider;
  907. /*Makes an ortho slice slider's appearance*/
  908. {
  909.     ObjPtr slicer, var;
  910.     real value;
  911.     int whichDimension;
  912.     real *el1;
  913.     FuncTyp method;
  914.  
  915.     slicer = GetObjectVar("MakeOrthoSliceAppearance", slider, REPOBJ);
  916.     if (!slicer)
  917.     {
  918.     return NULLOBJ;
  919.     }
  920.  
  921.     var = GetIntVar("MakeOrthoSliceAppearance", slider, WHICHINDEX);
  922.     if (!var)
  923.     {
  924.     return ObjFalse;
  925.     }
  926.     whichDimension = GetInt(var);
  927.  
  928.     var = GetArrayVar("MakeOrthoSliceAppearance", slicer, DIMVALUES);
  929.     if (!var)
  930.     {
  931.     return ObjFalse;
  932.     }
  933.     el1 = ELEMENTS(var);
  934.  
  935.     if (el1[whichDimension] > -0.5)
  936.     {
  937.     /*It needs to be active with this value*/
  938.     method = GetMethod(slider, CHANGEDVALUE);
  939.     SetMethod(slider, CHANGEDVALUE, (FuncTyp) 0);
  940.     ActivateSlider(slider, true);
  941.     SetValue(slider, NewReal(el1[whichDimension]));
  942.     SetMethod(slider, CHANGEDVALUE, method);
  943.     }
  944.     else
  945.     {
  946.     /*It needs to be inactive with null value*/
  947.     method = GetMethod(slider, CHANGEDVALUE);
  948.     SetMethod(slider, CHANGEDVALUE, (FuncTyp) 0);
  949.     ActivateSlider(slider, false);
  950.     SetValue(slider, NULLOBJ);
  951.     SetMethod(slider, CHANGEDVALUE, method);
  952.     }
  953.  
  954.     SetVar(slider, APPEARANCE, ObjTrue);
  955.  
  956.     return ObjTrue;
  957. }
  958.  
  959. static ObjPtr MakeSliceActiveAppearance(checkBox)
  960. ObjPtr checkBox;
  961. /*Makes the appearance of an active slice check box*/
  962. {
  963.     ObjPtr var;
  964.     real *elements;
  965.     ObjPtr repObj;
  966.     ObjPtr value;
  967.     FuncTyp method;
  968.     int whichIndex;
  969.  
  970.     repObj = GetObjectVar("MakeSliceActiveAppearance", checkBox, REPOBJ);
  971.     if (!repObj)
  972.     {
  973.     return ObjFalse;
  974.     }
  975.  
  976.     value = GetValue(checkBox);
  977.     if (!value)
  978.     {
  979.     return ObjFalse;
  980.     }
  981.  
  982.     var = GetIntVar("MakeSliceActiveAppearance", checkBox, WHICHINDEX);
  983.     if (!var)
  984.     {
  985.     return ObjFalse;
  986.     }
  987.     whichIndex = GetInt(var);
  988.  
  989.     var = GetArrayVar("MakeSliceActiveAppearance", repObj, DIMVALUES);
  990.     if (!var)
  991.     {
  992.     return ObjFalse;
  993.     }
  994.  
  995.     elements = ELEMENTS(var);
  996.     if (elements[whichIndex] > -0.5)
  997.     {
  998.     /*It's supposed to be on*/
  999.     if (!IsTrue(value))
  1000.     {
  1001.         /*Have to change the value*/
  1002.         method = GetMethod(checkBox, CHANGEDVALUE);
  1003.         SetMethod(checkBox, CHANGEDVALUE, (FuncTyp) 0);
  1004.         SetValue(checkBox, NewInt(1));
  1005.         SetMethod(checkBox, CHANGEDVALUE, method);
  1006.     }
  1007.     }
  1008.     else
  1009.     {
  1010.     /*It's supposed to be off*/
  1011.     if (IsTrue(value))
  1012.     {
  1013.         /*Have to change the value*/
  1014.         method = GetMethod(checkBox, CHANGEDVALUE);
  1015.         SetMethod(checkBox, CHANGEDVALUE, (FuncTyp) 0);
  1016.         SetValue(checkBox, NewInt(0));
  1017.         SetMethod(checkBox, CHANGEDVALUE, method);
  1018.     }
  1019.     }
  1020.  
  1021.     SetVar(checkBox, APPEARANCE, ObjTrue);
  1022. }
  1023.  
  1024. static ObjPtr ChangedSliceActive(checkBox)
  1025. ObjPtr checkBox;
  1026. /*Changed value for slice active check box*/
  1027. {
  1028.     ObjPtr var, changedVar;
  1029.     real *elements;
  1030.     real *changedElements;
  1031.     ObjPtr repObj;
  1032.     ObjPtr value;
  1033.     FuncTyp method;
  1034.     int whichIndex;
  1035.     int k;
  1036.     int smallest;
  1037.     real smallestVal;
  1038.     int lastDimChanged;
  1039.  
  1040.     repObj = GetObjectVar("ChangedSliceActive", checkBox, REPOBJ);
  1041.     if (!repObj)
  1042.     {
  1043.     return ObjFalse;
  1044.     }
  1045.  
  1046.     var = GetIntVar("ChangedSliceActive", repObj, LASTDIMCHANGED);
  1047.     if (!var)
  1048.     {
  1049.     return ObjFalse;
  1050.     }
  1051.     lastDimChanged = GetInt(var) + 1;
  1052.  
  1053.     value = GetValue(checkBox);
  1054.     if (!value)
  1055.     {
  1056.     return ObjFalse;
  1057.     }
  1058.  
  1059.     var = GetIntVar("ChangedSliceActive", checkBox, WHICHINDEX);
  1060.     if (!var)
  1061.     {
  1062.     return ObjFalse;
  1063.     }
  1064.     whichIndex = GetInt(var);
  1065.  
  1066.     var = GetArrayVar("ChangedSliceActive", repObj, DIMVALUES);
  1067.     if (!var)
  1068.     {
  1069.     return ObjFalse;
  1070.     }
  1071.  
  1072.     elements = ELEMENTS(var);
  1073.     if (IsTrue(value))
  1074.     {
  1075.     /*It's turned on*/
  1076.     if (elements[whichIndex] < -0.5)
  1077.     {
  1078.         /*It was off, so there's a transition*/
  1079.         var = NewRealArray(1, DIMS(var)[0]);
  1080.         CArray2Array(var, elements);
  1081.         elements = ELEMENTS(var);
  1082.  
  1083.         /*Now, have to turn off the oldest one turned on that's not me*/
  1084.         changedVar = GetArrayVar("ChangedSliceActive", repObj, DIMCHANGES);
  1085.         if (!changedVar)
  1086.         {
  1087.         return ObjFalse;
  1088.         }
  1089.         changedElements = ELEMENTS(changedVar);
  1090.  
  1091.         smallest = -1;
  1092.         for (k = 0; k < DIMS(changedVar)[0]; ++k)
  1093.         {
  1094.         if ((k != whichIndex) && (elements[k] > -0.5))
  1095.         {
  1096.             if (smallest < 0)
  1097.             {
  1098.             smallest = k;
  1099.             smallestVal = changedElements[k];
  1100.             }
  1101.             else
  1102.             {
  1103.             if (changedElements[k] < smallestVal)
  1104.             {
  1105.                 smallest = k;
  1106.                 smallestVal = changedElements[k];
  1107.             }
  1108.             }
  1109.         }
  1110.         }
  1111.  
  1112.         if (smallest >= 0)
  1113.         {
  1114.         elements[smallest] = -1.0;
  1115.         }
  1116.         elements[whichIndex] = 0.0;
  1117.         changedElements[whichIndex] = (real) lastDimChanged;
  1118.  
  1119.         SetVar(repObj, LASTDIMCHANGED, NewInt(lastDimChanged));
  1120.         SetVar(repObj, DIMVALUES, var);
  1121.         SetVar(repObj, DIMCHANGES, changedVar);
  1122.         SetVar(checkBox, APPEARANCE, ObjTrue);
  1123.     }
  1124.     }
  1125.     else
  1126.     {
  1127.     /*It's turned off.  Just touch the DIMVALUDS; 
  1128.       it'll come back on again*/
  1129.     SetVar(repObj, DIMVALUES, GetVar(repObj, DIMVALUES));
  1130.     }
  1131.  
  1132.     ImInvalid(repObj);
  1133.     return ObjTrue;
  1134. }
  1135.  
  1136. static ObjPtr AddOrthoSlicerControls(slicer, panelContents)
  1137. ObjPtr slicer;
  1138. ObjPtr panelContents;
  1139. /*Makes a new control window to control an ortho slicer*/
  1140. {
  1141.     ObjPtr var;
  1142.     ObjPtr parent;
  1143.     long info;
  1144.     ObjPtr textBox, checkBox, icon, titleBox, radio, controlField, name, button, slider;
  1145.     ObjPtr origDims, dimValues, mainDataset;
  1146.     real *el1, *el2;
  1147.     int i, k, y;
  1148.     int nDimensions;
  1149.     int left, right, bottom, top;
  1150.     char *s;
  1151.     ObjPtr contents;
  1152.     WinInfoPtr dialog;
  1153.  
  1154.     mainDataset = GetObjectVar("ShowOrthoSlicerControls", slicer, MAINDATASET);
  1155.     if (!mainDataset)
  1156.     {
  1157.     return ObjFalse;
  1158.     }
  1159.     origDims = GetDatasetFormDims(mainDataset);
  1160.     if (!origDims)
  1161.     {
  1162.     return ObjFalse;
  1163.     }
  1164.  
  1165.     MakeVar(slicer, DIMVALUES);
  1166.     dimValues = GetArrayVar("GetOrthoSlicerTopDim", slicer, DIMVALUES);
  1167.     if (!dimValues)
  1168.     {
  1169.     return ObjFalse;
  1170.     }
  1171.  
  1172.     left = MINORBORDER;
  1173.     right = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH - MINORBORDER;
  1174.     bottom = MINORBORDER;
  1175.     top = CWINHEIGHT - MINORBORDER;
  1176.  
  1177.     /*Determine if a control field is neccessary*/
  1178.     nDimensions = 0;
  1179.     el1 = ELEMENTS(dimValues);
  1180.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1181.     {
  1182.     if (el1[k] > -0.5)
  1183.     {
  1184.         /*Fixed dimension*/
  1185.         ++nDimensions;
  1186.     }
  1187.     }
  1188.  
  1189.     if (nDimensions * (OS_CONTROLWIDTH + MAJORBORDER) >
  1190.         (right - left))
  1191.     {
  1192.     /*Create a control field*/
  1193.     int scrollBars;
  1194.  
  1195.     right = (right - left - 2 - MINORBORDER);
  1196.     left = MINORBORDER;
  1197.     bottom = - (top - bottom - 2 - MINORBORDER);
  1198.     top = -MINORBORDER;
  1199.     scrollBars = 0;    
  1200.  
  1201.     if (nDimensions * (OS_CONTROLWIDTH + MAJORBORDER) >
  1202.         (right - left))
  1203.     {
  1204.         scrollBars |= BARBOTTOM;
  1205.         bottom += BARWIDTH + CORRALBARBORDER;
  1206.     }
  1207.  
  1208.     controlField = NewControlField(MINORBORDER,
  1209.             CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH - MINORBORDER,
  1210.             MINORBORDER, CWINHEIGHT - MINORBORDER,
  1211.              "Dimension controls", OBJECTSFROMTOP | scrollBars);    
  1212.     if (!controlField)
  1213.     {
  1214.         return ObjFalse;
  1215.     }
  1216.     PrefixList(panelContents, controlField);
  1217.     SetVar(controlField, PARENT, panelContents);
  1218.     SetVar(controlField, BACKGROUND, NewInt(UIBACKGROUND));
  1219.     SetVar(controlField, BORDERTYPE, NewInt(1));
  1220.     contents = GetVar(controlField, CONTENTS);
  1221.     parent = controlField;
  1222.     }
  1223.     else
  1224.     {
  1225.     /*No control field is needed*/
  1226.     controlField = NULLOBJ;
  1227.     contents = panelContents;
  1228.     parent = panelContents;
  1229.     }
  1230.  
  1231.  
  1232.     /*Create the control groups*/
  1233.     nDimensions = 0;
  1234.     el2 = ELEMENTS(origDims);
  1235.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1236.     {
  1237.         ObjPtr scale; 
  1238.  
  1239.         /*Fixed dimension, emit a series of controls*/
  1240.         char tempName[200], tempValue[50];
  1241.  
  1242.         right = left + OS_CONTROLWIDTH;
  1243.  
  1244.         /*Create the slice text box*/
  1245.         if (nDimensions <= 10)
  1246.         {
  1247.         sprintf(tempName, "%c axis (%d)", nDimensions + 'i', nDimensions);
  1248.         }
  1249.         else
  1250.         {
  1251.         sprintf(tempName, "Axis %d", nDimensions);
  1252.         }
  1253.         textBox = NewTextBox(left, right,
  1254.                 top - TEXTBOXHEIGHT, top,
  1255.                 0, tempName, tempName);
  1256.         SetVar(textBox, PARENT, parent);
  1257.         PrefixList(contents, textBox);
  1258.         SetTextAlign(textBox, CENTERALIGN);
  1259.  
  1260.         /*Create the slider*/
  1261.         sprintf(tempName, "Slice %d", nDimensions);
  1262.         slider = NewSlider(right - SLIDERWIDTH, right,
  1263.             bottom + EDITBOXHEIGHT + CHECKBOXHEIGHT + 2 * MINORBORDER, top - TEXTBOXHEIGHT - MINORBORDER,
  1264.             SCALE, tempName);
  1265.         PrefixList(contents, slider);
  1266.         SetVar(slider, PARENT, parent);
  1267.         sprintf(tempName, "Slice Scale %d", nDimensions);
  1268.         scale = NewScale(left, right - SLIDERWIDTH, 
  1269.             bottom + EDITBOXHEIGHT + CHECKBOXHEIGHT + 2 * MINORBORDER, top - TEXTBOXHEIGHT - MINORBORDER,
  1270.             SO_LEFT, false, tempName);
  1271.         LinkScale(scale, slider);
  1272.         PrefixList(contents, scale);
  1273.         SetVar(scale, PARENT, parent);
  1274.         SetSliderRange(slider, el2[k] - 1.0, 0.0, 1.0);
  1275.         SetSliderScale(slider, 5.0, 1.0, 0.0, "%g");
  1276.         if (el1[k] < -0.5)
  1277.         {
  1278.         SetSliderValue(slider, 0.0);
  1279.         }
  1280.         else
  1281.         {
  1282.         SetSliderValue(slider, el1[k]);
  1283.         }
  1284.          SetVar(slider, WHICHINDEX, NewInt(k));
  1285.         SetVar(slider, REPOBJ, slicer);
  1286.         SetMethod(slider, CHANGEDVALUE, ChangeOrthoSlice);
  1287.         DeclareIndirectDependency(slider, APPEARANCE, REPOBJ, DIMVALUES);
  1288.         SetMethod(slider, APPEARANCE, MakeOrthoSliceAppearance);
  1289.         /*Create the slider readout*/
  1290.         sprintf(tempName, "Slice Readout %d", nDimensions);
  1291.         if (el1[k] < -0.5)
  1292.         {
  1293.         sprintf(tempValue, "Free");
  1294.         }
  1295.         else
  1296.         {
  1297.         sprintf(tempValue, "%d", (int) (el1[k] + 0.5));
  1298.         }
  1299.         textBox = NewTextBox(left, right,
  1300.         bottom + CHECKBOXHEIGHT + MINORBORDER, bottom + CHECKBOXHEIGHT + MINORBORDER + EDITBOXHEIGHT,
  1301.         EDITABLE + WITH_PIT + ONE_LINE, tempName, tempValue);
  1302.         SetVar(textBox, PARENT, parent);
  1303.         PrefixList(contents, textBox);
  1304.         SetTextAlign(textBox, RIGHTALIGN);
  1305.         SliderReadout(slider, textBox);
  1306.         if (el1[k] < -0.5)
  1307.         {
  1308.         ActivateSlider(slider, false);
  1309.         }
  1310.  
  1311.         /*Make the activate check box*/
  1312.         if (nDimensions <= 10)
  1313.         {
  1314.         sprintf(tempName, "%c Active", nDimensions + 'i', nDimensions);
  1315.         }
  1316.         else
  1317.         {
  1318.         sprintf(tempName, "%d Active", nDimensions);
  1319.         }
  1320.         checkBox = NewRadioButton(left, right,
  1321.         bottom, bottom + CHECKBOXHEIGHT, tempName);
  1322.         SetVar(checkBox, PARENT, parent);
  1323.         SetVar(checkBox, WHICHINDEX, NewInt(k));
  1324.         PrefixList(contents, checkBox);
  1325.         SetVar(checkBox, REPOBJ, slicer);
  1326.         MakeButtonToggled(checkBox, true);
  1327.         SetMethod(checkBox, CHANGEDVALUE, ChangedSliceActive);
  1328.         DeclareIndirectDependency(checkBox, APPEARANCE, REPOBJ, DIMVALUES);
  1329.         SetMethod(checkBox, APPEARANCE, MakeSliceActiveAppearance);
  1330.  
  1331.         left = right + MAJORBORDER;
  1332.         ++nDimensions;
  1333.     }
  1334.  
  1335.     if (controlField)
  1336.     {
  1337.     RecalcScroll(controlField);
  1338.     }
  1339.  
  1340.     return ObjTrue;
  1341. }
  1342.  
  1343. /****************************************************************************/
  1344. /*                              Fixed Slicer                                */
  1345. /****************************************************************************/
  1346.  
  1347. static ObjPtr InitFixedSlicer(slicer, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  1348. ObjPtr slicer, dataset;
  1349. long desFlags;
  1350. int desTopDim, desSpatDim, desNComponents;
  1351. /*Initializes a fixed slicer
  1352.     slicer        the slicer
  1353.     dataset        the dataset to slice
  1354.     desFlags    the desired flags of the result
  1355.     desTopDim    the desired topological dimension
  1356.     desSpatDim    the desired spatial dimension
  1357.     desNComponents    the desired number of components
  1358.  
  1359. Returns ObjTrue if successful, ObjFalse if not
  1360. */
  1361. {
  1362.     long sourceInfo;
  1363.     ObjPtr var;
  1364.     int sourceTop, sourceSpatial, sourceNComponents;
  1365.     ObjPtr icon;
  1366.     ObjPtr dimValues;
  1367.     ObjPtr formDims;
  1368.     real *elements, *elements2;
  1369.     int k, validDims;
  1370.  
  1371.     /*Cannot deal with a list of datasets*/
  1372.     if (IsList(dataset))
  1373.     {
  1374.     return ObjFalse;
  1375.     }
  1376.  
  1377.     sourceInfo = GetDatasetInfo(dataset);
  1378.     sourceTop = GetTopDim(dataset);
  1379.     sourceSpatial = GetSpatialDim(dataset);
  1380.  
  1381.     /*Check the info*/
  1382.     if (sourceInfo & DS_UNSTRUCTURED ||
  1383.     !(sourceInfo & DS_HASFIELD))
  1384.     {
  1385.     return ObjFalse;
  1386.     }
  1387.  
  1388.     if (desFlags & DS_UNSTRUCTURED ||
  1389.     !(desFlags & DS_HASFIELD))
  1390.     {
  1391.     return ObjFalse;
  1392.     }
  1393.     if ((sourceInfo & (DS_VECTOR)) != (desFlags & (DS_VECTOR)))
  1394.     {
  1395.     return ObjFalse;
  1396.     }
  1397.  
  1398.     /*Check the topological dimension*/
  1399.     if (desTopDim >= 0 && desTopDim >= sourceTop)
  1400.     {
  1401.     return ObjFalse;
  1402.     }
  1403.  
  1404.     /*Check the spatial dimension*/
  1405.     if (desSpatDim >= 0 && desSpatDim != sourceSpatial)
  1406.     {
  1407.     return ObjFalse;
  1408.     }
  1409.     if (desSpatDim < 0) desSpatDim = sourceSpatial;
  1410.  
  1411.     /*See how many of the dimensions are degenerate*/
  1412.     formDims = GetDatasetFormDims(dataset);
  1413.     if (!formDims)
  1414.     {
  1415.     return ObjFalse;
  1416.     }
  1417.     elements = ELEMENTS(formDims);
  1418.  
  1419.     validDims = 0;
  1420.     for (k = 0; k < DIMS(formDims)[0]; ++k)
  1421.     {
  1422.     if (elements[k] >= 1.5)
  1423.     {
  1424.         ++validDims;
  1425.     }
  1426.     }
  1427.  
  1428.     if (desTopDim < 0)
  1429.     {
  1430.     desTopDim = validDims;
  1431.     }
  1432.     else if (desTopDim != validDims)
  1433.     {
  1434.     return ObjFalse;
  1435.     }
  1436.     if (desTopDim >= sourceTop)
  1437.     {
  1438.     return ObjFalse;
  1439.     }
  1440.  
  1441.     /*Check the n components*/
  1442.     var = GetVar(dataset, NCOMPONENTS);
  1443.     if (var)
  1444.     {
  1445.     sourceNComponents = GetInt(var);
  1446.     SetVar(slicer, NCOMPONENTS, var);
  1447.     }
  1448.     else
  1449.     {
  1450.     sourceNComponents = 1;
  1451.     }
  1452.     if (desNComponents >= 0 && (sourceNComponents != desNComponents))
  1453.     {
  1454.     return ObjFalse;
  1455.     }
  1456.     if (desNComponents < 0) desNComponents = sourceNComponents;
  1457.  
  1458.     /*OK now*/
  1459.  
  1460.     /*Choose an icon*/
  1461.     switch(desTopDim)
  1462.     {
  1463.     case 0:
  1464.     case 1:
  1465.         icon = sourceInfo & DS_VECTOR ? icon1DVector : icon1DScalar;
  1466.         break;
  1467.     case 2:
  1468.         icon = sourceInfo & DS_VECTOR ? icon2DVector : icon2DScalar;
  1469.         break;
  1470.     case 3:
  1471.         icon = sourceInfo & DS_VECTOR ? icon3DVector : icon3DScalar;
  1472.         break;
  1473.     default:
  1474.         icon = sourceInfo & DS_VECTOR ? icon4DVector : icon4DScalar;
  1475.         break;
  1476.     }
  1477.  
  1478.     icon = NewObject(icon, 0);
  1479.     SetVar(slicer, DEFAULTICON, icon);
  1480.  
  1481.     SetVar(slicer, NAME, GetVar(dataset, NAME));
  1482.     SetVar(icon, NAME, GetVar(dataset, NAME));
  1483.  
  1484.     /*Set the dataset*/
  1485.     SetVar(slicer, MAINDATASET, dataset);
  1486.  
  1487.     /*Create the DIMVALUES*/
  1488.     dimValues = NewRealArray(1, (long) sourceTop);
  1489.     elements = ELEMENTS(dimValues);
  1490.     elements2 = ELEMENTS(formDims);
  1491.     for (k = 0; k < sourceTop; ++k)
  1492.     {
  1493.     elements[k] = (elements2[k] < 1.5) ? 0.0: -1.0;
  1494.     }
  1495.     SetVar(slicer, DIMVALUES, dimValues);
  1496.  
  1497.     return ObjTrue;
  1498. }
  1499.  
  1500. static ObjPtr AllFixedSlicers(slicerClass, datasets)
  1501. ObjPtr slicerClass, datasets;
  1502. /*Returns a list of all possible slicers that can be made with datasets, or null*/
  1503. {
  1504.     long sourceInfo;
  1505.     long desFlags;
  1506.     ObjPtr var;
  1507.     int sourceTop, sourceSpatial, sourceNComponents;
  1508.     int desTop, desSpatial, desNComponents;
  1509.     ObjPtr icon;
  1510.     ObjPtr dimValues;
  1511.     real *elements;
  1512.     int k;
  1513.     ObjPtr retVal;
  1514.     ThingListPtr runner;
  1515.  
  1516.     retVal = NULLOBJ;
  1517.     for (runner = LISTOF(datasets); runner; runner = runner -> next)
  1518.     {
  1519.     ObjPtr dataset;
  1520.     dataset = runner -> thing;
  1521.     sourceInfo = GetDatasetInfo(dataset);
  1522.     sourceTop = GetTopDim(dataset);
  1523.     sourceSpatial = GetSpatialDim(dataset);
  1524.  
  1525.     /*Check the info*/
  1526.     if (sourceInfo & DS_UNSTRUCTURED ||
  1527.     !(sourceInfo & DS_HASFIELD))
  1528.     {
  1529.     continue;
  1530.     }
  1531.  
  1532.     desFlags = sourceInfo;
  1533.  
  1534.     /*Check the topological dimension*/
  1535.     if (sourceTop <= 0)
  1536.     {
  1537.     continue;
  1538.     }
  1539.  
  1540.     desSpatial = sourceSpatial;
  1541.     /*Check the n components*/
  1542.     var = GetVar(dataset, NCOMPONENTS);
  1543.     if (var)
  1544.     {
  1545.     sourceNComponents = GetInt(var);
  1546.     }
  1547.     else
  1548.     {
  1549.     sourceNComponents = 1;
  1550.     }
  1551.     desNComponents = sourceNComponents;
  1552.  
  1553.     for (desTop = 0; desTop < sourceTop; ++desTop)
  1554.     {
  1555.     ObjPtr slicer;
  1556.     slicer = NewObject(fixedSlicerClass, 0);
  1557.     if (IsTrue(InitFilter(slicer, dataset, desFlags, desTop, desSpatial, desNComponents)))
  1558.     {
  1559.         if (!retVal)
  1560.         {
  1561.         retVal = NewList();
  1562.         }
  1563.         PrefixList(retVal, slicer);
  1564.     }
  1565.     }
  1566.     }
  1567.     return retVal;
  1568. }
  1569.  
  1570. static ObjPtr GetFixedSlicerLongName(slicer)
  1571. ObjPtr slicer;
  1572. {
  1573.     ObjPtr retVal, mainDataset;
  1574.  
  1575.     sprintf(tempStr, " Fixed slice");
  1576.     retVal = NewString(tempStr);
  1577.     mainDataset = GetVar(slicer, MAINDATASET);
  1578.     if (mainDataset)
  1579.     {
  1580.     retVal = ConcatStrings(GetLongName(mainDataset), retVal);
  1581.     }
  1582.     return retVal;
  1583. }
  1584.  
  1585. static ObjPtr GetFixedSlicerTopDim(slicer)
  1586. ObjPtr slicer;
  1587. /*Returns the topological dimension of slicer*/
  1588. {
  1589.     ObjPtr dimValues;
  1590.     int nDimensions, k;
  1591.     real *elements;
  1592.  
  1593.     MakeVar(slicer, DIMVALUES);
  1594.     dimValues = GetArrayVar("GetFixedSlicerTopDim", slicer, DIMVALUES);
  1595.     if (!dimValues)
  1596.     {
  1597.     return NULLOBJ;
  1598.     }
  1599.  
  1600.     nDimensions = 0;
  1601.     elements = ELEMENTS(dimValues);
  1602.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1603.     {
  1604.     if (elements[k] < -0.5)
  1605.     {
  1606.         /*Free dimension*/
  1607.         ++nDimensions;
  1608.     }
  1609.     }
  1610.  
  1611.     return NewInt(nDimensions);
  1612. }
  1613.  
  1614. static ObjPtr GetFixedSlicerSpatialDim(slicer)
  1615. ObjPtr slicer;
  1616. /*Returns the spatial dimension of slicer*/
  1617. {
  1618.     ObjPtr mainDataset;
  1619.     mainDataset = GetObjectVar("GetFixedSlicerSpatialDim", slicer, MAINDATASET);
  1620.     if (mainDataset)
  1621.     {
  1622.     return NewInt(GetSpatialDim(mainDataset));
  1623.     }
  1624.     else
  1625.     {
  1626.     return NULLOBJ;
  1627.     }
  1628. }
  1629.  
  1630. static ObjPtr GetFixedSlicerInfo(slicer)
  1631. ObjPtr slicer;
  1632. /*Gets info for a fixed slicer*/
  1633. {
  1634.     ObjPtr mainDataset;
  1635.     mainDataset = GetObjectVar("GetFixedSlicerInfo", slicer, MAINDATASET);
  1636.     if (mainDataset)
  1637.     {
  1638.     return NewInt(GetDatasetInfo(mainDataset));
  1639.     }
  1640.     else
  1641.     {
  1642.     return NULLOBJ;
  1643.     }
  1644. }
  1645.  
  1646. static ObjPtr MakeFixedSlicerCPalette(slicer)
  1647. ObjPtr slicer;
  1648. /*Makes the fixed slicers's CPALETTE*/
  1649. {
  1650.     ObjPtr mainDataset;
  1651.     mainDataset = GetObjectVar("MakeFixedSlicerCPalette", slicer, MAINDATASET);
  1652.     if (mainDataset)
  1653.     {
  1654.     SetVar(slicer, CPALETTE, GetVar(mainDataset, CPALETTE));
  1655.     return ObjTrue;
  1656.     }
  1657.     else
  1658.     {
  1659.     return ObjFalse;
  1660.     }
  1661. }
  1662.  
  1663. static ObjPtr MakeFixedSlicerDataForm(slicer)
  1664. ObjPtr slicer;
  1665. /*Makes a fixed slicer's dataform.*/
  1666. {
  1667.     ObjPtr mainDataset;
  1668.  
  1669.     mainDataset = GetObjectVar("MakeFixedSlicerDataForm", slicer, MAINDATASET);
  1670.     if (mainDataset)
  1671.     {
  1672.     SetVar(slicer, DATAFORM, GetVar(mainDataset, DATAFORM));
  1673.     return ObjTrue;
  1674.     }
  1675.     else
  1676.     {
  1677.     return ObjFalse;
  1678.     }
  1679. }
  1680.  
  1681. static ObjPtr GetFixedSlicerFormDims(slicer)
  1682. ObjPtr slicer;
  1683. /*Gets form dims for a fixed slicer*/
  1684. {
  1685.     ObjPtr mainDataset;
  1686.     ObjPtr origDims, resultDims, dimValues;
  1687.     int nDimensions, k;
  1688.     real *el1, *el2, *el3;
  1689.  
  1690.     mainDataset = GetObjectVar("GetFixedSlicerFormDims", slicer, MAINDATASET);
  1691.     if (!mainDataset)
  1692.     {
  1693.     return NULLOBJ;
  1694.     }
  1695.  
  1696.     origDims = GetDatasetFormDims(mainDataset);
  1697.     if (!origDims)
  1698.     {
  1699.     return NULLOBJ;
  1700.     }
  1701.  
  1702.     MakeVar(slicer, DIMVALUES);
  1703.     dimValues = GetArrayVar("GetFixedSlicerFormDims", slicer, DIMVALUES);
  1704.     if (!dimValues)
  1705.     {
  1706.     return NULLOBJ;
  1707.     }
  1708.  
  1709.     nDimensions = 0;
  1710.     el1= ELEMENTS(dimValues);
  1711.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1712.     {
  1713.     if (el1[k] < -0.5)
  1714.     {
  1715.         /*Free dimension*/
  1716.         ++nDimensions;
  1717.     }
  1718.     }
  1719.  
  1720.     if (nDimensions == 0)
  1721.     {
  1722.     return NULLOBJ;
  1723.     }
  1724.     resultDims = NewRealArray(1, (long) nDimensions);
  1725.     el2 = ELEMENTS(origDims);
  1726.     el3 = ELEMENTS(resultDims);
  1727.     nDimensions = 0;
  1728.     
  1729.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1730.     {
  1731.     if (el1[k] < -0.5)
  1732.     {
  1733.         /*Free dimension*/
  1734.         el3[nDimensions] = el2[k];
  1735.         ++nDimensions;
  1736.     }
  1737.     }
  1738.  
  1739.     return resultDims;
  1740. }
  1741.  
  1742. static ObjPtr RegisterFixedSlicerField(slicer, whichField)
  1743. ObjPtr slicer;
  1744. int whichField;
  1745. /*Registers the field for a fixed slicer*/
  1746. {
  1747.     ObjPtr mainDataset;
  1748.     ObjPtr origDims, resultDims, dimValues;
  1749.     int nDimensions, k, d, i, comp;
  1750.     real *el1, *el2, *el3;
  1751.     long *tempIndices;
  1752.     long offset;
  1753.  
  1754.     mainDataset = GetObjectVar("RegisterFixedSlicerField", slicer, MAINDATASET);
  1755.     if (!mainDataset)
  1756.     {
  1757.     return NULLOBJ;
  1758.     }
  1759.  
  1760.     /*Let the main dataset register itself*/
  1761.     if (!SetCurField(whichField, mainDataset))
  1762.     {
  1763.     return ObjFalse;
  1764.     }
  1765.  
  1766.     /*Now edit it, based on dimValues*/
  1767.     MakeVar(slicer, DIMVALUES);
  1768.     dimValues = GetArrayVar("GetFixedSlicerTopDim", slicer, DIMVALUES);
  1769.     if (!dimValues)
  1770.     {
  1771.     return NULLOBJ;
  1772.     }
  1773.  
  1774.     /*Calculate the number of dimensions*/
  1775.     nDimensions = 0;
  1776.     el1= ELEMENTS(dimValues);
  1777.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1778.     {
  1779.     if (el1[k] < -0.5)
  1780.     {
  1781.         /*Free dimension*/
  1782.         ++nDimensions;
  1783.     }
  1784.     }
  1785.     curFields[whichField] . topDim = nDimensions;
  1786.  
  1787.     /*Set up some temporary indices for testing*/
  1788.     tempIndices = (long *) Alloc(DIMS(dimValues)[0] * sizeof(long));
  1789.     if (!tempIndices)
  1790.     {
  1791.     return ObjFalse;
  1792.     }
  1793.     el1= ELEMENTS(dimValues);
  1794.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1795.     {
  1796.     if (el1[k] < -0.5)
  1797.     {
  1798.         /*Free dimension.  Make it 0*/
  1799.         tempIndices[k] = 0;
  1800.     }
  1801.     else
  1802.     {
  1803.         /*Not Free.*/
  1804.         tempIndices[k] = (long) (el1[k] + 0.5);
  1805.     }
  1806.     }
  1807.  
  1808.     /*Go through the components, editing them*/
  1809.     for (comp = 0; comp < curFields[whichField] . nComponents; ++comp)
  1810.     {
  1811.     /*Get the base offset*/
  1812.     offset = GetComponentOffset(whichField, comp, tempIndices);
  1813.  
  1814.     /*Nudge up the base ptr by that offset*/
  1815.     if (curFields[whichField] . components[comp] . dataCompressed)
  1816.     {
  1817.         curFields[whichField] . components[comp] . data . comp += offset;
  1818.     }
  1819.     else
  1820.     {
  1821.         curFields[whichField] . components[comp] . data . unComp += offset;
  1822.     }
  1823.  
  1824.     /*Make invalid any fixed indices*/
  1825.     for (k = 0; k < curFields[whichField] . components[comp] . nIndices; ++k)
  1826.     {
  1827.         if (el1[curFields[whichField] . components[comp] . indices[k]] > -0.5)
  1828.         {
  1829.         /*Fixed index, already accounted for*/
  1830.         curFields[whichField] . components[comp] . indices[k] = -1;
  1831.         }
  1832.         else
  1833.         {
  1834.         /*Variable index, have to shift down*/
  1835.         d = 0;
  1836.         for (i = 0; i < curFields[whichField] . components[comp] . indices[k]; ++i)
  1837.         {
  1838.             if (el1[i] < -0.5)
  1839.             {
  1840.             ++d;
  1841.             }
  1842.         }
  1843.         curFields[whichField] . components[comp] . indices[k] = d;
  1844.         }
  1845.     }
  1846.     }
  1847.     
  1848.     Free(tempIndices);
  1849.     return ObjTrue;
  1850. }
  1851.  
  1852. static ObjPtr RegisterFixedSlicerForm(slicer, whichField)
  1853. ObjPtr slicer;
  1854. int whichField;
  1855. /*Registers the form for a fixed slicer*/
  1856. {
  1857.     ObjPtr mainDataset;
  1858.     ObjPtr origDims, resultDims, dimValues;
  1859.     int nDimensions, k, d, i, comp;
  1860.     real *el1, *el2, *el3;
  1861.     long *tempIndices;
  1862.     long offset;
  1863.  
  1864.     mainDataset = GetObjectVar("RegisterFixedSlicerForm", slicer, MAINDATASET);
  1865.     if (!mainDataset)
  1866.     {
  1867.     return NULLOBJ;
  1868.     }
  1869.  
  1870.     /*Let the main dataset register itself*/
  1871.     if (!SetCurForm(whichField, mainDataset))
  1872.     {
  1873.     return ObjFalse;
  1874.     }
  1875.  
  1876.     /*Now edit it, based on dimValues*/
  1877.     MakeVar(slicer, DIMVALUES);
  1878.     dimValues = GetArrayVar("RegisterFixedSlicerForm", slicer, DIMVALUES);
  1879.     if (!dimValues)
  1880.     {
  1881.     return NULLOBJ;
  1882.     }
  1883.  
  1884.     /*Calculate the number of dimensions*/
  1885.     nDimensions = 0;
  1886.     el1= ELEMENTS(dimValues);
  1887.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1888.     {
  1889.     if (el1[k] < -0.5)
  1890.     {
  1891.         /*Free dimension*/
  1892.         ++nDimensions;
  1893.     }
  1894.     }
  1895.     curFields[whichField] . topDim = nDimensions;
  1896.  
  1897.     /*Set up some temporary indices for testing*/
  1898.     tempIndices = (long *) Alloc(DIMS(dimValues)[0] * sizeof(long));
  1899.     if (!tempIndices)
  1900.     {
  1901.     return ObjFalse;
  1902.     }
  1903.     el1= ELEMENTS(dimValues);
  1904.     for (k = 0; k < DIMS(dimValues)[0]; ++k)
  1905.     {
  1906.     if (el1[k] < -0.5)
  1907.     {
  1908.         /*Free dimension.  Make it 0*/
  1909.         tempIndices[k] = 0;
  1910.     }
  1911.     else
  1912.     {
  1913.         /*Not Free.*/
  1914.         tempIndices[k] = (long) (el1[k] + 0.5);
  1915.     }
  1916.     }
  1917.  
  1918.     /*Go through the components, editing them*/
  1919.     for (comp = 0; comp < curFields[whichField] . nComponents; ++comp)
  1920.     {
  1921.     /*Get the base offset*/
  1922.     offset = GetComponentOffset(whichField, comp, tempIndices);
  1923.     
  1924.     /*Nudge up the base ptr by that offset*/
  1925.     if (curFields[whichField] . components[comp] . dataCompressed)
  1926.     {
  1927.         curFields[whichField] . components[comp] . data . comp += offset;
  1928.     }
  1929.     else
  1930.     {
  1931.         curFields[whichField] . components[comp] . data . unComp += offset;
  1932.     }
  1933.  
  1934.     /*Make invalid any fixed indices*/
  1935.     for (k = 0; k < curFields[whichField] . components[comp] . nIndices; ++k)
  1936.     {
  1937.         if (el1[curFields[whichField] . components[comp] . indices[k]] > -0.5)
  1938.         {
  1939.         /*Fixed index, already accounted for*/
  1940.         curFields[whichField] . components[comp] . indices[k] = -1;
  1941.         }
  1942.         else
  1943.         {
  1944.         /*Variable index, have to shift down*/
  1945.         d = 0;
  1946.         for (i = 0; i < curFields[whichField] . components[comp] . indices[k]; ++i)
  1947.         {
  1948.             if (el1[i] < -0.5)
  1949.             {
  1950.             ++d;
  1951.             }
  1952.         }
  1953.         curFields[whichField] . components[comp] . indices[k] = d;
  1954.         }
  1955.     }
  1956.     }
  1957.     
  1958.     Free(tempIndices);
  1959.     return ObjTrue;
  1960. }
  1961.  
  1962. /****************************************************************************/
  1963. /*                             Missing Data                                 */
  1964. /* Handles disposition and definition of missing data                       */
  1965. /****************************************************************************/
  1966.  
  1967. static ObjPtr InitMissingData(misser, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  1968. ObjPtr misser, dataset;
  1969. long desFlags;
  1970. int desTopDim, desSpatDim, desNComponents;
  1971. /*Initializes a missing data handler
  1972.     misser        the missing data object
  1973.     dataset        the dataset to slice
  1974.     desFlags    the desired flags of the result
  1975.     desTopDim    the desired topological dimension
  1976.     desSpatDim    the desired spatial dimension
  1977.     desNComponents    the desired number of components
  1978.  
  1979. Returns ObjTrue if successful, ObjFalse if not
  1980. */
  1981. {
  1982.     long sourceInfo;
  1983.     ObjPtr var;
  1984.     int sourceTop, sourceSpatial, sourceNComponents;
  1985.     ObjPtr icon;
  1986.     ObjPtr dimValues;
  1987.     ObjPtr formDims;
  1988.     real *elements, *elements2;
  1989.     int k, validDims;
  1990.  
  1991.     /*Cannot deal with a list of datasets*/
  1992.     if (IsList(dataset))
  1993.     {
  1994.     return ObjFalse;
  1995.     }
  1996.  
  1997.     sourceInfo = GetDatasetInfo(dataset);
  1998.     sourceTop = GetTopDim(dataset);
  1999.     sourceSpatial = GetSpatialDim(dataset);
  2000.  
  2001.     if ((sourceInfo & DS_HASGEOMETRY) || (sourceInfo & DS_HASNEWGEOMETRY))
  2002.     {
  2003.     return ObjFalse;
  2004.     }
  2005.  
  2006.     /*See about the number of components*/
  2007.     if (sourceInfo & DS_VECTOR)
  2008.     {
  2009.     MakeVar(dataset, NCOMPONENTS);
  2010.     var = GetVar(dataset, NCOMPONENTS);
  2011.     if (!var || GetInt(var) != desNComponents)
  2012.     {
  2013.     return ObjFalse;
  2014.     }
  2015.     SetVar(misser, NCOMPONENTS, NewInt(desNComponents));
  2016.     }
  2017.  
  2018.     /*OK now*/
  2019.     
  2020.     /*Choose an icon*/
  2021.     MakeVar(dataset, DEFAULTICON);
  2022.     icon = GetVar(dataset, DEFAULTICON);
  2023.     SetVar(misser, DEFAULTICON, icon);
  2024.     SetVar(misser, NAME, GetVar(dataset, NAME));
  2025.     SetVar(icon, NAME, GetVar(dataset, NAME));
  2026.  
  2027.     /*Set the dataset*/
  2028.     SetVar(misser, MAINDATASET, dataset);
  2029.  
  2030.     return ObjTrue;
  2031. }
  2032.  
  2033. static ObjPtr AllMissingDatas(missingDataClass, datasets)
  2034. ObjPtr missingDataClass, datasets;
  2035. /*Returns a list of all possible missers that can be made with datasets, or null*/
  2036. {
  2037.     long sourceInfo;
  2038.     long desFlags;
  2039.     ObjPtr var;
  2040.     int sourceTop, sourceSpatial, sourceNComponents;
  2041.     int desTop, desSpatial, desNComponents;
  2042.     ObjPtr icon;
  2043.     ObjPtr dimValues;
  2044.     real *elements;
  2045.     int k;
  2046.     ObjPtr retVal;
  2047.     ThingListPtr runner;
  2048.  
  2049.     retVal = NULLOBJ;
  2050.     for (runner = LISTOF(datasets); runner; runner = runner -> next)
  2051.     {
  2052.     ObjPtr dataset;
  2053.     dataset = runner -> thing;
  2054.     sourceInfo = GetDatasetInfo(dataset);
  2055.     sourceTop = GetTopDim(dataset);
  2056.     sourceSpatial = GetSpatialDim(dataset);
  2057.  
  2058.     /*Check the info*/
  2059.     if ((sourceInfo & DS_HASGEOMETRY) || (sourceInfo & DS_HASNEWGEOMETRY))
  2060.     {
  2061.         continue;
  2062.     }
  2063.  
  2064.     for (desTop = 0; desTop < sourceTop; ++desTop)
  2065.     {
  2066.         ObjPtr misser;
  2067.         misser = NewObject(missingDataClass, 0);
  2068.         if (IsTrue(InitFilter(misser, dataset, desFlags, desTop, desSpatial, desNComponents)))
  2069.         {
  2070.         if (!retVal)
  2071.         {
  2072.             retVal = NewList();
  2073.         }
  2074.         PrefixList(retVal, misser);
  2075.         }
  2076.     }
  2077.     }
  2078.     return retVal;
  2079. }
  2080.  
  2081. static ObjPtr GetMissingDataLongName(misser)
  2082. ObjPtr misser;
  2083. {
  2084.     ObjPtr mainDataset;
  2085.  
  2086.     mainDataset = GetVar(misser, MAINDATASET);
  2087.  
  2088.     return GetLongName(mainDataset);
  2089. }
  2090.  
  2091. static ObjPtr GetMissingDataTopDim(misser)
  2092. ObjPtr misser;
  2093. /*Returns the topological dimension of missing data*/
  2094. {
  2095.     ObjPtr dataset;
  2096.  
  2097.     dataset = GetVar(misser, MAINDATASET);
  2098.     return NewInt(GetTopDim(dataset));
  2099. }
  2100.  
  2101. static ObjPtr GetMissingDataSpatialDim(misser)
  2102. ObjPtr misser;
  2103. /*Returns the spatial dimension of misser*/
  2104. {
  2105.     ObjPtr mainDataset;
  2106.     mainDataset = GetObjectVar("GetMissingDataSpatialDim", misser, MAINDATASET);
  2107.     if (mainDataset)
  2108.     {
  2109.     return NewInt(GetSpatialDim(mainDataset));
  2110.     }
  2111.     else
  2112.     {
  2113.     return NULLOBJ;
  2114.     }
  2115. }
  2116.  
  2117. static ObjPtr GetMissingDataInfo(misser)
  2118. ObjPtr misser;
  2119. /*Gets info for a fixed misser*/
  2120. {
  2121.     ObjPtr mainDataset;
  2122.     mainDataset = GetObjectVar("GetMissingDataInfo", misser, MAINDATASET);
  2123.     if (mainDataset)
  2124.     {
  2125.     return NewInt(GetDatasetInfo(mainDataset));
  2126.     }
  2127.     else
  2128.     {
  2129.     return NULLOBJ;
  2130.     }
  2131. }
  2132.  
  2133. static ObjPtr MakeMissingDataCPalette(misser)
  2134. ObjPtr misser;
  2135. /*Makes the missing data's CPALETTE*/
  2136. {
  2137.     ObjPtr mainDataset;
  2138.     mainDataset = GetObjectVar("MakeMissingDataCPalette", misser, MAINDATASET);
  2139.     if (mainDataset)
  2140.     {
  2141.     SetVar(misser, CPALETTE, GetVar(mainDataset, CPALETTE));
  2142.     return ObjTrue;
  2143.     }
  2144.     else
  2145.     {
  2146.     return ObjFalse;
  2147.     }
  2148. }
  2149.  
  2150. static ObjPtr MakeMissingDataForm(misser)
  2151. ObjPtr misser;
  2152. /*Makes a missing data's dataform.*/
  2153. {
  2154.     ObjPtr mainDataset;
  2155.  
  2156.     mainDataset = GetObjectVar("MakeMissingDataDataForm", misser, MAINDATASET);
  2157.     if (mainDataset)
  2158.     {
  2159.     SetVar(misser, DATAFORM, GetVar(mainDataset, DATAFORM));
  2160.     return ObjTrue;
  2161.     }
  2162.     else
  2163.     {
  2164.     return ObjFalse;
  2165.     }
  2166. }
  2167.  
  2168. static ObjPtr GetMissingDataFormDims(misser)
  2169. ObjPtr misser;
  2170. /*Gets form dims for a fixed misser*/
  2171. {
  2172.     ObjPtr mainDataset;
  2173.     ObjPtr origDims;
  2174.  
  2175.     mainDataset = GetVar(misser, MAINDATASET);
  2176.  
  2177.     origDims = GetDatasetFormDims(mainDataset);
  2178.     if (!origDims)
  2179.     {
  2180.     return NULLOBJ;
  2181.     }
  2182.     return origDims;
  2183. }
  2184.  
  2185. static ObjPtr RegisterMissingDataField(misser, whichField)
  2186. ObjPtr misser;
  2187. int whichField;
  2188. /*Registers the field for a missing data thingie*/
  2189. {
  2190.     ObjPtr mainDataset;
  2191.     ObjPtr var;
  2192.  
  2193.     mainDataset = GetObjectVar("RegisterMissingDataField", misser, MAINDATASET);
  2194.     if (!mainDataset)
  2195.     {
  2196.     return NULLOBJ;
  2197.     }
  2198.  
  2199.     /*Let the main dataset register itself*/
  2200.     if (!SetCurField(whichField, mainDataset))
  2201.     {
  2202.     return ObjFalse;
  2203.     }
  2204.  
  2205.     /*If there's a funny thing to do with missing data, do it*/
  2206.     var = GetVar(misser, HANDLEMISSING);
  2207.     if (var && GetInt(var))
  2208.     {
  2209.     var = GetVar(misser, MISSINGSUBST);
  2210.     if (var)
  2211.     {
  2212.         curFields[whichField] . substMissing = true;
  2213.         curFields[whichField] . missingVal = GetReal(var);
  2214.     }
  2215.     }
  2216.     else
  2217.     {
  2218.     curFields[whichField] . substMissing = false;
  2219.     }
  2220.     return ObjTrue;
  2221. }
  2222.  
  2223. static ObjPtr RegisterMissingDataForm(misser, whichField)
  2224. ObjPtr misser;
  2225. int whichField;
  2226. /*Registers the form for a missing data thingie*/
  2227. {
  2228.     ObjPtr mainDataset;
  2229.  
  2230.     mainDataset = GetObjectVar("RegisterMissingDataForm", misser, MAINDATASET);
  2231.     if (!mainDataset)
  2232.     {
  2233.     return NULLOBJ;
  2234.     }
  2235.  
  2236.     /*Let the main dataset register itself*/
  2237.     if (!SetCurForm(whichField, mainDataset))
  2238.     {
  2239.     return ObjFalse;
  2240.     }
  2241.  
  2242.     return ObjTrue;
  2243. }
  2244.  
  2245. static ObjPtr AddMissingDataControls(misser, panelContents)
  2246. ObjPtr misser;
  2247. ObjPtr panelContents;
  2248. /*Makes a new control window to control a missing data filter*/
  2249. {
  2250.     ObjPtr titleBox, radioButton, textBox, radioGroup, var;
  2251.  
  2252.     titleBox = TemplateTitleBox(MissingDataTemplate, "Handle Missing Data");
  2253.     PrefixList(panelContents, titleBox);
  2254.     SetVar(titleBox, PARENT, panelContents);
  2255.  
  2256.     radioGroup = NewRadioButtonGroup("Handle Missing Data Radio");
  2257.     SetVar(radioGroup, PARENT, panelContents);
  2258.     PrefixList(panelContents, radioGroup);
  2259.  
  2260.     radioButton = TemplateRadioButton(MissingDataTemplate, "Treat As Missing");
  2261.     SetVar(radioButton, HELPSTRING, NewString("When this button is on, missing \
  2262. data points are passed to the visualization object as is.  This usually results in gaps \
  2263. in the visualization object where data points are missing."));
  2264.     AddRadioButton(radioGroup, radioButton);
  2265.  
  2266.     radioButton = TemplateRadioButton(MissingDataTemplate, "Treat As:");
  2267.     SetVar(radioButton, HELPSTRING, NewString("When this button is on, missing \
  2268. data points are treated as the numeric value given in the text box to the right.  For \
  2269. example, if this button is on and there is a 0 in the text box, missing data \
  2270. points will be treated as if they were zero."));
  2271.     AddRadioButton(radioGroup, radioButton);
  2272.  
  2273.     PrefixList(panelContents, radioGroup);
  2274.     SetVar(radioGroup, PARENT, panelContents);
  2275.  
  2276.     textBox = TemplateTextBox(MissingDataTemplate, "Missing Value", 
  2277.         EDITABLE + ONE_LINE + WITH_PIT, "");
  2278.     PrefixList(panelContents, textBox);
  2279.     SetVar(textBox, PARENT, panelContents);
  2280.     SetVar(textBox, REPOBJ, misser);
  2281.  
  2282.     AssocDirectControlWithVar(radioGroup, misser, HANDLEMISSING);
  2283.     if (!GetVar(misser, MISSINGSUBST)) SetVar(misser, MISSINGSUBST, NewReal(0.0));
  2284.     AssocTextRealControlWithVar(textBox, misser, MISSINGSUBST, minusInf, plusInf, TR_MISSING_OK);
  2285.  
  2286.     return ObjTrue;
  2287. }
  2288.  
  2289. /****************************************************************************/
  2290. /*                            General functions                             */
  2291. /****************************************************************************/
  2292.  
  2293. static ObjPtr CloneFilter(filter)
  2294. ObjPtr filter;
  2295. /*Clones a filter*/
  2296. {
  2297.     FuncTyp method;
  2298.     ObjPtr newFilter;
  2299.     ObjPtr mainDataset;
  2300.  
  2301.     newFilter = Clone(filter);
  2302.     mainDataset = GetVar(newFilter, MAINDATASET);
  2303.     if (mainDataset)
  2304.     {
  2305.     method = GetMethod(mainDataset, CLONE);
  2306.     if (method)
  2307.     {
  2308.         mainDataset = (*method)(mainDataset);
  2309.         SetVar(newFilter, MAINDATASET, mainDataset);
  2310.     }
  2311.     }
  2312.     return newFilter;
  2313. }
  2314.  
  2315. void RegisterEasyFilter(filter)
  2316. ObjPtr filter;
  2317. /*Registers filter*/
  2318. {
  2319.     PrefixList(registeredEasyFilters, filter);
  2320. }
  2321.  
  2322. void RegisterMainFilter(filter)
  2323. ObjPtr filter;
  2324. /*Registers filter as one to be applied always to datasets*/
  2325. {
  2326.     PrefixList(registeredMainFilters, filter);
  2327. }
  2328.  
  2329. int mdsSerialNumber = 0;
  2330.  
  2331. static ObjPtr GetFilterMinMax(object)
  2332. ObjPtr object;
  2333. /*Gets a filter's min and max*/
  2334. {
  2335.     ObjPtr mainDataset;
  2336.     MakeVar(object, MAINDATASET);
  2337.     mainDataset = GetVar(object, MAINDATASET);
  2338.     MakeVar(mainDataset, MINMAX);
  2339.     SetVar(object, MINMAX, GetVar(mainDataset, MINMAX));
  2340.     return ObjTrue;
  2341. }
  2342.  
  2343. ObjPtr datasetsToModify = NULLOBJ;
  2344.  
  2345. void SetupModifyList()
  2346. /*Sets up a list of objects to modify*/
  2347. {
  2348.     EmptyList(datasetsToModify);
  2349. }
  2350.  
  2351. ObjPtr ModifyDataset(object)
  2352. ObjPtr object;
  2353. /*Modifies the dataset (actually just sticks it on the list)*/
  2354. {
  2355.     PrefixList(datasetsToModify, object);
  2356. }
  2357.  
  2358. void ModifyDatasets()
  2359. {
  2360.     DoObjFunction(OF_MODIFY);
  2361. }
  2362.  
  2363. ObjPtr AllEasyFilters(list)
  2364. ObjPtr list;
  2365. /*Returns all the easy filters for the elements in list*/
  2366. {
  2367.     ObjPtr allFilters;
  2368.     ThingListPtr runner;
  2369.  
  2370.     allFilters = NULLOBJ;
  2371.  
  2372.     runner = LISTOF(registeredEasyFilters);
  2373.     while (runner)
  2374.     {
  2375.     ObjPtr filters;
  2376.     filters = AllFilters(runner -> thing, list);
  2377.     if (filters)
  2378.     {
  2379.         if (!allFilters)
  2380.         {
  2381.         allFilters = NewList();
  2382.         }
  2383.         AppendList(allFilters, filters);
  2384.     }
  2385.     runner = runner -> next;
  2386.     }
  2387.     return allFilters;
  2388. }
  2389.  
  2390. ObjPtr MainFilters(dataset)
  2391. ObjPtr dataset;
  2392. /*Returns a main filter for the dataset*/
  2393. {
  2394.     ThingListPtr runner;
  2395.     ObjPtr list;
  2396.  
  2397.     list = NewList();
  2398.     PrefixList(list, dataset);
  2399.  
  2400.     runner = LISTOF(registeredMainFilters);
  2401.     while (runner)
  2402.     {
  2403.     ObjPtr filters;
  2404.  
  2405.     filters = AllFilters(runner -> thing, list);
  2406.     if (filters && LISTOF(filters))
  2407.     {
  2408.         list = NewList();
  2409.         PrefixList(list, LISTOF(filters) -> thing);
  2410.     }
  2411.     runner = runner -> next;
  2412.     }
  2413.     return LISTOF(list) -> thing;
  2414. }
  2415.  
  2416. void ProcessModifyList()
  2417. /*Creates a window containing modifications for the selected icons*/
  2418. {
  2419.     WinInfoPtr newWindow;
  2420.     int l, r, b, t;
  2421.     int bw;
  2422.     ObjPtr objList;
  2423.     ObjPtr panel, contents, corral, button;
  2424.     ObjPtr allFilters;
  2425.     ThingListPtr runner;
  2426.  
  2427.     /*Go through the possible filters*/
  2428.     allFilters = AllEasyFilters(datasetsToModify);
  2429.  
  2430.     if (!allFilters)
  2431.     {
  2432.     /*No filters*/
  2433.     WinInfoPtr errWindow;
  2434.     if (IsList(datasetsToModify) && LISTOF(datasetsToModify) && 
  2435.         LISTOF(datasetsToModify) -> next)
  2436.     {
  2437.         WarnUser(CW_NOTOGETHERMODIFY);
  2438.     }
  2439.     else
  2440.     {
  2441.         WarnUser(CW_NOTOGETHERMODIFY);
  2442.     }
  2443.     EmptyList(datasetsToModify);
  2444.     return;
  2445.     }
  2446.  
  2447.     /*Create the window*/
  2448.     sprintf(tempStr, "Modified Datasets %d", ++mdsSerialNumber); 
  2449.     newWindow = NewObjWindow(NULLOBJ, tempStr, WINUI,
  2450.         MODWINWIDTH, MODWINHEIGHT, SCRWIDTH, SCRHEIGHT);
  2451.  
  2452.     /*Put in a panel*/
  2453.     panel = NewPanel(greyPanelClass, 0, MODWINWIDTH, 0, MODWINHEIGHT);
  2454.     SetVar(panel, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  2455.                      STICKYBOTTOM + STICKYTOP));
  2456.  
  2457.     contents = GetVar((ObjPtr) newWindow, CONTENTS);
  2458.     PrefixList(contents, panel);
  2459.     SetVar(panel, PARENT, (ObjPtr) newWindow);
  2460.  
  2461.     /*Put in buttons and an icon corral*/
  2462.     contents = GetListVar("ProcessModifyList", panel, CONTENTS);
  2463.     if (!contents)
  2464.     {
  2465.     return;
  2466.     }
  2467.  
  2468.     l = 0;
  2469.     r = MODWINWIDTH;
  2470.     b = 0;
  2471.     t = MODWINHEIGHT;
  2472.  
  2473.     /*Make an icon corral*/
  2474.     corral = NewIconCorral(NULLOBJ, l + MINORBORDER, r - MINORBORDER, b + 3 * MINORBORDER + 2 * BUTTONHEIGHT, t - MINORBORDER, BARRIGHT + BARBOTTOM);
  2475.     SetVar(corral, STICKINESS, NewInt(STICKYLEFT + STICKYRIGHT +
  2476.                      STICKYBOTTOM + STICKYTOP));
  2477.     SetVar(corral, NAME, NewString("Modifiers Corral"));
  2478.     SetVar((ObjPtr) newWindow, CORRAL, corral);
  2479.     SetVar(corral, TOPDOWN, ObjTrue);
  2480.     SetVar(corral, HELPSTRING,
  2481.     NewString("This corral contains icons for all the possible modifications \
  2482. of a dataset or group of datasets.  You can visualize, show the controls of, or modify the datasets by selecting \
  2483. some of them and pressing the buttons at the bottom of the window.  You can delete \
  2484. datasets by choosing Delete from the Object menu."));
  2485.     PrefixList(contents, corral);
  2486.     SetVar(corral, PARENT, panel);
  2487.  
  2488.     l += MINORBORDER;
  2489.     r -= MINORBORDER;
  2490.     b += 2 * MINORBORDER + BUTTONHEIGHT;
  2491.     t = b + BUTTONHEIGHT;
  2492.     bw = (r - l - MINORBORDER) / 2;
  2493.  
  2494.     /*Make a visualize button*/
  2495.     button = NewFunctionButton(newWindow,
  2496.         l, l + bw,
  2497.         b, b + BUTTONHEIGHT, OF_VISUALIZE); 
  2498.     if (button)
  2499.     {
  2500.     SetVar(button, PARENT, panel);
  2501.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + STICKYLEFT + FLOATINGRIGHT));
  2502.     PrefixList(contents, button);
  2503.     }
  2504.  
  2505.     /*Make a visualize as... button*/
  2506.     button = NewFunctionButton(newWindow,
  2507.         r - bw, r,
  2508.         b, b + BUTTONHEIGHT, OF_VISUALIZE_AS); 
  2509.     if (button)
  2510.     {
  2511.     SetVar(button, PARENT, panel);
  2512.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + FLOATINGLEFT + STICKYRIGHT));
  2513.     PrefixList(contents, button);
  2514.     }
  2515.  
  2516.     t = b - MINORBORDER;
  2517.     b = t - BUTTONHEIGHT;
  2518.  
  2519.     /*Make a show controls button*/
  2520.     button = NewFunctionButton(newWindow,
  2521.         l, l + bw, 
  2522.         b, b + BUTTONHEIGHT, OF_SHOW_CONTROLS); 
  2523.     if (button)
  2524.     {
  2525.     SetVar(button, PARENT, panel);
  2526.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + STICKYLEFT + FLOATINGRIGHT));
  2527.     PrefixList(contents, button);
  2528.     }
  2529.  
  2530.     /*Make a modify button*/
  2531.     button = NewFunctionButton(newWindow, r - bw, 
  2532.         r,
  2533.         b, b + BUTTONHEIGHT, OF_MODIFY);
  2534.     if (button)
  2535.     {
  2536.     SetVar(button, PARENT, panel);
  2537.     SetVar(button, STICKINESS, NewInt(STICKYBOTTOM + FLOATINGLEFT + STICKYRIGHT));
  2538.     PrefixList(contents, button);
  2539.     }
  2540.  
  2541.     /*Put allFilters in the corral*/
  2542.     runner = LISTOF(allFilters);
  2543.  
  2544.     while(runner)
  2545.     {
  2546.     ObjPtr icon, name;
  2547.     FuncTyp method;
  2548.     
  2549.     icon = GetVar(runner -> thing, DEFAULTICON);
  2550.     if (!icon)
  2551.     {
  2552.         icon = NewIcon(0, 0, ICONQUESTION, "?");
  2553.     }
  2554.     else
  2555.     {
  2556.         icon = NewObject(icon, 0L);
  2557.     }
  2558.     method = GetMethodSurely("ModifyDatasets", runner -> thing, GETLONGNAME);
  2559.     if (method)
  2560.     {
  2561.         name = (*method)(runner -> thing);
  2562.         SetVar(icon, NAME, name);
  2563.     }
  2564.  
  2565.     SetVar(icon, ICONLOC, NULLOBJ);
  2566.     SetVar(icon, REPOBJ, runner -> thing);
  2567.     SetVar(icon, CORRAL, corral);
  2568.     DropIconSeriesInCorral(corral, icon);
  2569.  
  2570.     runner = runner -> next;
  2571.     }
  2572.     EmptyModifyList();
  2573. }
  2574.  
  2575. void EmptyModifyList()
  2576. {
  2577.     EmptyList(datasetsToModify);
  2578. }
  2579.  
  2580. ObjPtr InitFilter(filter, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  2581. ObjPtr filter, dataset;
  2582. long desFlags;
  2583. int desTopDim, desSpatDim, desNComponents;
  2584. /*Initializes a filter*/
  2585. {
  2586.     FuncTyp method;
  2587.     method = GetMethod(filter, INITFILTER);
  2588.     if (method)
  2589.     {
  2590.     return (*method)(filter, dataset, desFlags, desTopDim, desSpatDim, desNComponents);
  2591.     }
  2592.     else
  2593.     {
  2594.     return ObjFalse;
  2595.     }
  2596. }
  2597.  
  2598. ObjPtr NewFilter(filterClass, dataset, desFlags, desTopDim, desSpatDim, desNComponents)
  2599. ObjPtr filterClass, dataset;
  2600. long desFlags;
  2601. int desTopDim, desSpatDim, desNComponents;
  2602. /*Makes a new filter and initializes it*/
  2603. {
  2604.     ObjPtr filter;
  2605.  
  2606.     filter = NewObject(filterClass, 0L);
  2607.     if (IsTrue(InitFilter(filter, dataset, desFlags, desTopDim, desSpatDim, desNComponents)))
  2608.     {
  2609.     return filter;
  2610.     }
  2611.     else
  2612.     {
  2613.     return NULLOBJ;
  2614.     }
  2615. }
  2616.  
  2617. ObjPtr AllFilters(filterClass, dataset)
  2618. ObjPtr filterClass, dataset;
  2619. /*Returns all the filters that can modify dataset*/
  2620. {
  2621.     FuncTyp method;
  2622.     method = GetMethod(filterClass, ALLFILTERS);
  2623.     if (method)
  2624.     {
  2625.     return (*method)(filterClass, dataset);
  2626.     }
  2627.     else
  2628.     {
  2629.     return NULLOBJ;
  2630.     }
  2631. }
  2632.  
  2633. ObjPtr MakeFilterTimeSteps(filter)
  2634. ObjPtr filter;
  2635. /*Makes a filter's TIMESTEPS*/
  2636. {
  2637.     ObjPtr dataset;
  2638.  
  2639.     MakeVar(filter, MAINDATASET);
  2640.     dataset = GetVar(filter, MAINDATASET);
  2641.     if (dataset)
  2642.     {
  2643.     SetVar(filter, TIMESTEPS, GetVar(dataset, TIMESTEPS));
  2644.     }
  2645.     return ObjTrue;
  2646. }
  2647.  
  2648. ObjPtr MakeFilterTimeFormat(filter)
  2649. ObjPtr filter;
  2650. /*Makes a filter's TIMEFORMAT*/
  2651. {
  2652.     ObjPtr dataset;
  2653.  
  2654.     MakeVar(filter, MAINDATASET);
  2655.     dataset = GetVar(filter, MAINDATASET);
  2656.     if (dataset)
  2657.     {
  2658.     MakeVar(dataset, TIMEFORMAT);
  2659.     SetVar(filter, TIMEFORMAT, GetVar(dataset, TIMEFORMAT));
  2660.     }
  2661.     return ObjTrue;
  2662. }
  2663.  
  2664. static ObjPtr MakeFilterChanged(filter)
  2665. ObjPtr filter;
  2666. /*Makes a filter changed*/
  2667. {
  2668.     SetVar(filter, CHANGED, ObjTrue);
  2669.     return ObjTrue;
  2670. }
  2671.  
  2672. static ObjPtr MakeFilterXName(filter)
  2673. ObjPtr filter;
  2674. /*Makes a filter's XNAME*/
  2675. {
  2676.     ObjPtr mainDataset;
  2677.  
  2678.     MakeVar(filter, MAINDATASET);
  2679.     mainDataset = GetVar(filter, MAINDATASET);
  2680.  
  2681.     if (mainDataset)
  2682.     {
  2683.     MakeVar(mainDataset, XNAME);
  2684.     SetVar(filter, XNAME, GetVar(mainDataset, XNAME));
  2685.     }
  2686.     else
  2687.     {
  2688.     SetVar(filter, XNAME, NULLOBJ);
  2689.     }
  2690. }
  2691.  
  2692. static ObjPtr MakeFilterYName(filter)
  2693. ObjPtr filter;
  2694. /*Makes a filter's YNAME*/
  2695. {
  2696.     ObjPtr mainDataset;
  2697.  
  2698.     MakeVar(filter, MAINDATASET);
  2699.     mainDataset = GetVar(filter, MAINDATASET);
  2700.  
  2701.     if (mainDataset)
  2702.     {
  2703.     MakeVar(mainDataset, YNAME);
  2704.     SetVar(filter, YNAME, GetVar(mainDataset, YNAME));
  2705.     }
  2706.     else
  2707.     {
  2708.     SetVar(filter, YNAME, NULLOBJ);
  2709.     }
  2710. }
  2711.  
  2712. static ObjPtr MakeFilterZName(filter)
  2713. ObjPtr filter;
  2714. /*Makes a filter's ZNAME*/
  2715. {
  2716.     ObjPtr mainDataset;
  2717.  
  2718.     MakeVar(filter, MAINDATASET);
  2719.     mainDataset = GetVar(filter, MAINDATASET);
  2720.  
  2721.     if (mainDataset)
  2722.     {
  2723.     MakeVar(mainDataset, ZNAME);
  2724.     SetVar(filter, ZNAME, GetVar(mainDataset, ZNAME));
  2725.     }
  2726.     else
  2727.     {
  2728.     SetVar(filter, ZNAME, NULLOBJ);
  2729.     }
  2730. }
  2731.  
  2732. void InitFilters()
  2733. /*Initializes the filters*/
  2734. {
  2735.     ObjPtr icon;
  2736.  
  2737.     datasetsToModify = NewList();
  2738.     AddToReferenceList(datasetsToModify);
  2739.  
  2740.     registeredEasyFilters = NewList();
  2741.     AddToReferenceList(registeredEasyFilters);
  2742.  
  2743.     registeredMainFilters = NewList();
  2744.     AddToReferenceList(registeredMainFilters);
  2745.  
  2746.     SetMethod(datasetClass, MODIFY, ModifyDataset);
  2747.     filterClass = NewObject(datasetClass, 0);
  2748.     AddToReferenceList(filterClass);
  2749.     SetMethod(filterClass, CLONE, CloneFilter);
  2750.     SetMethod(filterClass, CLEANUP, (FuncTyp) 0);
  2751.     SetMethod(filterClass, SHOWCONTROLS, NewControlWindow);
  2752.     SetMethod(filterClass, MINMAX, GetFilterMinMax);
  2753.     DeclareIndirectDependency(filterClass, TIMESTEPS, MAINDATASET, TIMESTEPS);
  2754.     SetMethod(filterClass, TIMESTEPS, MakeFilterTimeSteps);
  2755.     DeclareIndirectDependency(filterClass, TIMEFORMAT, MAINDATASET, TIMEFORMAT);
  2756.     SetMethod(filterClass, TIMEFORMAT, MakeFilterTimeFormat);
  2757.     SetMethod(filterClass, XNAME, MakeFilterXName);
  2758.     SetMethod(filterClass, YNAME, MakeFilterYName);
  2759.     SetMethod(filterClass, ZNAME, MakeFilterZName);
  2760.     DeclareIndirectDependency(filterClass, CHANGED, MAINDATASET, CHANGED);
  2761.     SetMethod(filterClass, CHANGED, MakeFilterChanged);
  2762.     SetMethod(filterClass, RENAME, (FuncTyp) 0);
  2763.  
  2764.     /*Orthogonal slicer filter*/
  2765.     orthoSlicerClass = NewObject(filterClass, 0);
  2766.     SetVar(orthoSlicerClass, NAME, NewString("Ortho Slice"));
  2767.     SetMethod(orthoSlicerClass, INITFILTER, InitOrthoSlicer);
  2768.     SetMethod(orthoSlicerClass, GETDATASETINFO, GetOrthoSlicerInfo);
  2769.     SetMethod(orthoSlicerClass, GETTOPDIM, GetOrthoSlicerTopDim);
  2770.     SetMethod(orthoSlicerClass, GETSPATIALDIM, GetOrthoSlicerSpatialDim);
  2771.     SetMethod(orthoSlicerClass, GETFORMDIMS, GetOrthoSlicerFormDims);
  2772.     SetMethod(orthoSlicerClass, REGISTERFIELD, RegisterOrthoSlicerField);
  2773.     SetMethod(orthoSlicerClass, REGISTERFORM, RegisterOrthoSlicerForm);
  2774.     SetMethod(orthoSlicerClass, ADDCONTROLS, AddOrthoSlicerControls);
  2775.     SetMethod(orthoSlicerClass, GETLONGNAME, GetOrthoSlicerLongName);
  2776.     SetMethod(orthoSlicerClass, ALLFILTERS, AllOrthoSlicers);
  2777.     icon = NewIcon(0, 0, ICONSLICE, "Slice");
  2778.     SetVar(orthoSlicerClass, CONTROLICON, icon);
  2779.  
  2780.     DeclareDependency(orthoSlicerClass, CPALETTE, MAINDATASET);
  2781.     DeclareIndirectDependency(orthoSlicerClass, CPALETTE, MAINDATASET, CPALETTE);
  2782.     SetMethod(orthoSlicerClass, CPALETTE, MakeOrthoSlicerCPalette);
  2783.  
  2784.     DeclareDependency(orthoSlicerClass, DATAFORM, MAINDATASET);
  2785.     DeclareIndirectDependency(orthoSlicerClass, DATAFORM, MAINDATASET, DATAFORM);
  2786.     SetMethod(orthoSlicerClass, DATAFORM, MakeOrthoSlicerDataForm);
  2787.  
  2788.     RegisterEasyFilter(orthoSlicerClass);
  2789.  
  2790.     /*Missing data filter*/
  2791.     missingDataClass = NewObject(filterClass, 0);
  2792.     SetVar(missingDataClass, NAME, NewString("Missing Data"));
  2793.     SetMethod(missingDataClass, INITFILTER, InitMissingData);
  2794.     SetMethod(missingDataClass, GETDATASETINFO, GetMissingDataInfo);
  2795.     SetMethod(missingDataClass, GETTOPDIM, GetMissingDataTopDim);
  2796.     SetMethod(missingDataClass, GETSPATIALDIM, GetMissingDataSpatialDim);
  2797.     SetMethod(missingDataClass, GETFORMDIMS, GetMissingDataFormDims);
  2798.     SetMethod(missingDataClass, REGISTERFIELD, RegisterMissingDataField);
  2799.     SetMethod(missingDataClass, REGISTERFORM, RegisterMissingDataForm);
  2800.     SetMethod(missingDataClass, ADDCONTROLS, AddMissingDataControls);
  2801.     SetMethod(missingDataClass, GETLONGNAME, GetMissingDataLongName);
  2802.     SetMethod(missingDataClass, ALLFILTERS, AllMissingDatas);
  2803.     SetVar(missingDataClass, HANDLEMISSING, NewInt(0));
  2804.     SetVar(missingDataClass, MISSINGSUBST, NewReal(0.0));
  2805.     icon = NewIcon(0, 0, ICONMISSING, "Missing Data");
  2806.     SetVar(missingDataClass, CONTROLICON, icon);
  2807.  
  2808.     DeclareDependency(missingDataClass, CPALETTE, MAINDATASET);
  2809.     DeclareIndirectDependency(missingDataClass, CPALETTE, MAINDATASET, CPALETTE);
  2810.     SetMethod(missingDataClass, CPALETTE, MakeOrthoSlicerCPalette);
  2811.  
  2812.     DeclareDependency(missingDataClass, DATAFORM, MAINDATASET);
  2813.     DeclareIndirectDependency(missingDataClass, DATAFORM, MAINDATASET, DATAFORM);
  2814.     SetMethod(missingDataClass, DATAFORM, MakeOrthoSlicerDataForm);
  2815.  
  2816.     RegisterMainFilter(missingDataClass);
  2817.  
  2818.     /*Fixed slicer filter*/
  2819.     fixedSlicerClass = NewObject(filterClass, 0);
  2820.     SetVar(fixedSlicerClass, NAME, NewString("Fixed Slice"));
  2821.     SetMethod(fixedSlicerClass, INITFILTER, InitFixedSlicer);
  2822.     SetMethod(fixedSlicerClass, GETDATASETINFO, GetFixedSlicerInfo);
  2823.     SetMethod(fixedSlicerClass, GETTOPDIM, GetFixedSlicerTopDim);
  2824.     SetMethod(fixedSlicerClass, GETSPATIALDIM, GetFixedSlicerSpatialDim);
  2825.     SetMethod(fixedSlicerClass, GETFORMDIMS, GetFixedSlicerFormDims);
  2826.     SetMethod(fixedSlicerClass, REGISTERFIELD, RegisterFixedSlicerField);
  2827.     SetMethod(fixedSlicerClass, REGISTERFORM, RegisterFixedSlicerForm);
  2828.     SetMethod(fixedSlicerClass, GETLONGNAME, GetFixedSlicerLongName);
  2829.     SetMethod(fixedSlicerClass, ALLFILTERS, AllFixedSlicers);
  2830.  
  2831.     DeclareDependency(fixedSlicerClass, CPALETTE, MAINDATASET);
  2832.     DeclareIndirectDependency(fixedSlicerClass, CPALETTE, MAINDATASET, CPALETTE);
  2833.     SetMethod(fixedSlicerClass, CPALETTE, MakeFixedSlicerCPalette);
  2834.  
  2835.     DeclareDependency(fixedSlicerClass, DATAFORM, MAINDATASET);
  2836.     DeclareIndirectDependency(fixedSlicerClass, DATAFORM, MAINDATASET, DATAFORM);
  2837.     SetMethod(fixedSlicerClass, DATAFORM, MakeFixedSlicerDataForm);
  2838.  
  2839.     RegisterMainFilter(fixedSlicerClass);
  2840.  
  2841. #if 0
  2842.     /*Vector joiner filter*/
  2843.     vectorJoinerClass = NewObject(filterClass, 0);
  2844.     SetVar(vectorJoinerClass, NAME, NewString("Vector Joiner"));
  2845.     SetMethod(vectorJoinerClass, INITFILTER, InitVectorJoiner);
  2846.     SetMethod(vectorJoinerClass, ALLFILTERS, AllVectorJoiners);
  2847.     SetMethod(orthoSlicerClass, GETDATASETINFO, GetOrthoSlicerInfo);
  2848.     SetMethod(orthoSlicerClass, GETTOPDIM, GetOrthoSlicerTopDim);
  2849.     SetMethod(orthoSlicerClass, GETSPATIALDIM, GetOrthoSlicerSpatialDim);
  2850.     SetMethod(orthoSlicerClass, GETFORMDIMS, GetOrthoSlicerFormDims);
  2851.     SetMethod(orthoSlicerClass, REGISTERFIELD, RegisterOrthoSlicerField);
  2852.     SetMethod(orthoSlicerClass, REGISTERFORM, RegisterOrthoSlicerForm);
  2853.     SetMethod(orthoSlicerClass, ADDCONTROLS, AddOrthoSlicerControls);
  2854.     SetMethod(vectorJoinerClass, GETLONGNAME, GetOrthoSlicerLongName);
  2855.     icon = NewIcon(0, 0, ICONSLICE, "Slice");
  2856.     SetVar(orthoSlicerClass, CONTROLICON, icon);
  2857.  
  2858.     DeclareDependency(orthoSlicerClass, CPALETTE, MAINDATASET);
  2859.     DeclareIndirectDependency(orthoSlicerClass, CPALETTE, MAINDATASET, CPALETTE);
  2860.     SetMethod(orthoSlicerClass, CPALETTE, MakeOrthoSlicerCPalette);
  2861.  
  2862.     DeclareDependency(orthoSlicerClass, DATAFORM, MAINDATASET);
  2863.     DeclareIndirectDependency(orthoSlicerClass, DATAFORM, MAINDATASET, DATAFORM);
  2864.     SetMethod(orthoSlicerClass, DATAFORM, MakeOrthoSlicerDataForm);
  2865.  
  2866.     RegisterEasyFilter(vectorJoinerClass);
  2867. #endif
  2868.  
  2869. }
  2870.  
  2871. void KillFilters()
  2872. /*Kills the filters*/
  2873. {
  2874.     DeleteThing(filterClass);
  2875.     DeleteThing(registeredEasyFilters);
  2876.     DeleteThing(registeredMainFilters);
  2877.     DeleteThing(datasetsToModify);
  2878. }
  2879.